2010-10-21 3 views
5

J'utilise javascript pour exécuter un XMLHttpRequest sur un script PHP qui renvoie des données. Fondamentalement, je veux être en mesure de fournir à l'utilisateur une barre de progression (au lieu d'un cercle tournant ou quelque chose) qui montre la progression de l'obtention et la réception des données. Je sais que si je recevais un fichier, je pouvais simplement vérifier l'en-tête de la longueur du contenu et l'utiliser, mais dans le cas d'un script, vous ne savez pas combien de données il récupère.Obtention de la progression XMLHttpRequest à partir du script PHP

La réponse à cette question pourrait être aussi simple que «ce n'est pas possible», parce qu'à l'heure actuelle, cela semble être le cas. Mais en conclusion: Comment surveillez-vous la progression d'un script en cours (php) et XMLHttpRequest?

+0

Il pourrait y avoir une douzaine de façons différentes de le faire. Cela dépend de ce que fait le script PHP et du type de technologie côté serveur que vous avez. Peux-tu être plus précis? – mellowsoon

+0

Le script exécute des requêtes et utilise les données pour générer du code html, que le gestionnaire de réponse xmlhttprequest insère sur la page en cours. – Evan4623

Répondre

1

En haut de ma tête, vous pouvez utiliser 2 requêtes ajax. Un pour démarrer et attendre que le travail soit terminé, et un autre pour vérifier la progression du travail. Je suis sûr que la plupart des navigateurs peuvent faire au moins 2 requêtes ajax à la fois.

Le script PHP (appelons-le job.php) qui exécute le travail peut mettre à jour la variable de session $ _SESSION ['job_progress'] avec le pourcentage d'achèvement du travail.

Vous avez un autre script PHP (Appelons il progress.php) qui echos cette valeur, à savoir

<?php echo $_SESSION['job_progress']; 

côté client vous tirez votre demande ajax à job.php. Vous avez une autre requête ajax pour progress.php qui s'exécute toutes les 3 secondes. Vous mettez à jour votre barre de progression avec la valeur renvoyée.

Vous pouvez également le faire avec une requête ajax si la demande de job.php est renvoyée avant la fin du travail. Ensuite, vous pouvez continuer à utiliser une seule requête ajax pour envoyer un ping au script progress.php.

+0

Je pense qu'il veut savoir combien d'octets d'un fichier demandé avec XHR il a reçu jusqu'à présent. – GordonM

+0

@Gordon - Le même concept s'applique. – mellowsoon

+0

PHP ne conserve pas d'enregistrement du nombre d'octets envoyés sur une connexion donnée, donc je ne comprends pas vraiment comment utiliser une seconde connexion pour le demander serait utile. Si vous désactivez PHP dans l'exécution d'un travail qui prendrait beaucoup de temps à s'exécuter, vous pouvez utiliser votre solution pour lui demander combien de temps il pense avant que le travail ne soit terminé, mais dans le cas d'un travail qui se termine très rapidement mais dans beaucoup de données à envoyer cette approche ne fonctionnerait pas si bien. – GordonM

0

Dans certains navigateurs (firefox pour un), onreadystatechange avec readyState 3 (c'est-à-dire le chargement) est invoqué plusieurs fois pour que la progression du téléchargement puisse être surveillée.

De plus, dans certains navigateurs, la propriété responseText contient les résultats obtenus jusqu'à maintenant, et elle pourrait être examinée pour avoir une idée de la progression.

Cependant, Internet Explorer (au moins pour IE7, pas sûr plus tard) ne supporte pas, et il est une erreur d'interroger responseText ou responseBody pour readyState 3. J'ai aussi entendu l'IE appelle seulement onreadystatechange une fois avec readyState 3 qui le rendrait plutôt inutile pour votre usage, mais je suggère de le tester.

0

Créer une session. (Probablement, vous en avez déjà un). Créez un UID pour la requête lorsque vous lui demandez de commencer le traitement.

Stockez quelque part sur le serveur (dans la base de données, dans le fichier, etc.) une progression avec le SID + UID, à mesure que la requête progresse.

Utilisez une deuxième requête ajax avec timer pour interroger la progression par SID + UID.

* Vous ne pouvez obtenir que l'UID, probablement, mais je l'ai trouvé plus gérable quand vous pouviez aussi surveiller les tâches par utilisateur/session.

2

Si vous utilisez FireFox (et je suis assez sûr que la plupart des autres navigateurs que IE), il est en effet un moyen de signaler combien de données ont été transférées au cours d'une opération XHR. Si l'opération en question envoie l'en-tête correct, il est assez facile d'utiliser cette information pour calculer le pourcentage de données téléchargées.

J'ai écrit ce code pour déterminer le pourcentage de données transférées dans une opération XHR il y a des années, donc je m'excuse pour cela ne reflétant pas les années d'expérience de codage que j'ai acquise depuis. Je ne serais certainement pas l'écrire de cette façon maintenant! Pourtant, j'ai réussi à le pêcher, et j'espère que c'est utile pour vous.

Au moment où cela a été écrit, IE7 était la dernière version d'Explorer disponible, et je me souviens que le code ne fonctionnait pas dans ce sens, d'où il contient du code pour l'empêcher d'initialiser sous IE. Je n'ai jamais essayé ce code sous la version 8 ou la version bêta de la version 9, et il peut effectivement fonctionner dans ces versions, mais je ne peux pas le garantir. Si vous pouvez le faire fonctionner dans une nouvelle version d'IE, s'il vous plaît faites le moi savoir! Il fonctionne en exécutant le code dans beforeSend (un rappel jQuery fournit le code que vous voulez exécuter avant de lancer une requête ajax) pour configurer un intervalle Javascript (dans le code que j'ai mis 50 miliseconds, ce qui est probablement trop souvent 200 millisecondes devraient toujours être abondantes, et mettre moins de pression sur le système). Chaque fois que le temporisateur d'intervalle se déclenche, il exécute une fonction qui examine l'attribut responseText de la requête XHR. L'attribut responseText contient le texte brut des données reçues jusqu'à présent. En comptant le nombre de caractères présents avec la méthode string length(), nous pouvons déterminer le nombre d'octets collectés jusqu'à présent.

Pour calculer le pourcentage de données totales à envoyer, votre code côté serveur doit envoyer un en-tête de longueur de contenu avec un décompte précis du nombre d'octets qu'il va envoyer. Cela nécessitera un peu d'intelligence de votre part, mais ne devrait pas s'avérer trop difficile. Si vous envoyez un en-tête de longueur de contenu précis, il est utilisé pour calculer un pourcentage de données reçues jusqu'à présent. Si vous ne définissez pas d'en-tête de contenu, la quantité de données reçues jusqu'à présent s'affiche à la place.

<script type="text/javascript"> 
$.ajax ({ 
    beforeSend : function (thisXHR) 
    { 
     // IE doesn't support responseText access in interactive mode 
     if (!$.browser.msie) 
     { 
      myTrigger = setInterval (function() 
      { 
       if (thisXHR.readyState > 2) 
       // When there is partial data available use it to determine how much of the document is downloaded 
       { 
        var dlBytes = thisXHR.responseText.length; 
        if (totalBytes == -1) 
         totalBytes = thisXHR.getResponseHeader ('Content-length'); 
        (totalBytes > 0)? 
         $('#progress').html (Math.round ((dlBytes/totalBytes) * 100) + "%"): 
         $('#progress').html (Math.round (dlBytes/1024) + "K"); 
       } 
      }, 50); // Check the status every 50 miliseconds 
     } 
    }, 
    complete : function() 
    { 
     // Kill the download progress polling timer 
     if (myTrigger) 
      clearInterval (myTrigger); 
    } 
}); 
</script> 
Questions connexes