2010-07-28 4 views
16

J'essaie la nouvelle fonctionnalité XMLHTTPRequestUpload pour télécharger des fichiers sur un script php, cela fonctionne généralement bien, le téléchargement commence, je reçois la réponse de finition etc - mais la progression ne marche pas ne semble pas fonctionner.XHR Upload Progression est 100% depuis le début

En regardant que la valeur event.loaded - Dans firefox je semble obtenir une valeur aléatoire entre 0 et la taille du fichier; dans Chrome (où je travaille principalement) j'obtiens la taille totale de dossier, même si le readystate n'a pas atteint '4' et la fenêtre d'outils de développement montre toujours le dossier à charger?

Des idées?

Heres mon code:

var xhr = new XMLHttpRequest() 

xhr.upload.addEventListener('progress', function(event) { 
    if (event.lengthComputable) { 
     $('ajaxFeedbackDiv').innerHTML = event.loaded + '/' + event.total; 
    } 
}, false); 

xhr.onreadystatechange = function(event) { 
    if (event.target.readyState == 4) { 
     updateFileList(); 
    } 
}; 

xhr.open("POST", "_code/upload.php"); 
xhr.setRequestHeader("Cache-Control", "no-cache"); 
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 
xhr.setRequestHeader("X-File-Size", file.size); 
xhr.setRequestHeader("X-File-Type", file.type); 
xhr.setRequestHeader("Content-Type", "multipart/form-data"); 
xhr(file); 

Un grand merci

Ben

+0

Avez-vous trouvé une solution ou une solution de contournement au problème? Je ressens actuellement la même chose, mais cela semble dépendre de votre connexion réseau. Il fonctionne comme prévu dans un endroit, et saute à 100% de l'autre. – unclenorton

+3

Je rencontre le même problème. Fait intéressant, il semble que cela ne se produise que lorsque je cours sur localhost - quand je déploie sur nos serveurs dev ou prod, la valeur chargée revient comme on pouvait s'y attendre. – brettjonesdev

Répondre

16

J'ai aussi eu récemment un certain niveau de difficulté un écouteur d'événement pour les événements de XHR. J'ai fini par la mise en œuvre comme une fonction anonyme, qui fonctionne à merveille:

xhr.upload.onprogress = function(evt) 
{ 
    if (evt.lengthComputable) 
    { 
     var percentComplete = parseInt((evt.loaded/evt.total) * 100); 
     console.log("Upload: " + percentComplete + "% complete") 
    } 
}; 

Je suis tombé sur un beaucoup d'autres gotchas le long du chemin, cependant, il est donc fort probable de ceux trébuchait mon écouteur d'événement . La seule autre différence entre ce que vous avez et ma configuration est que j'utilise xhr.sendAsBinary().

0

J'ai rencontré moi-même un problème similaire, où ma fonction de gestionnaire d'événements pour progress événements sur XMLHttpRequest a été exécutée une seule fois - lorsque le téléchargement était terminé.

La cause du problème a fini par être simple - dans Google Chrome (éventuellement d'autres navigateurs, je n'ai pas testé), l'événement progress se déclenchera uniquement si le téléchargement a été exécuté pendant une seconde ou deux. En d'autres termes, si votre téléchargement se termine rapidement, vous obtiendrez probablement un événement 100% progress.

est ici un exemple de code dont l'événement progress déclenche une seule fois à 100% complète (https://jsfiddle.net/qahs40r6/):

$.ajax({ 
    xhr: function() 
    { 
    var xhr = new window.XMLHttpRequest(); 
    //Upload progress 
    xhr.upload.addEventListener("progress", function(evt){ 
     if (evt.lengthComputable) { 
     var percentComplete = evt.loaded/evt.total; 
     console.log("Upload ", Math.round(percentComplete*100) + "% complete."); 
     } 
    }, false); 
    return xhr; 
    }, 
    type: 'POST', 
    url: "/echo/json/", 
    data: {json: JSON.stringify(new Array(20000))} 
}); 

Sortie de la console:

Upload 100% complete. 

Mais si vous ajoutez un zéro supplémentaire à la taille de la matrice (augmentant la taille de la charge utile d'un facteur de 10 - https://jsfiddle.net/qahs40r6/1/):

$.ajax({ 
    xhr: function() 
    { 
    var xhr = new window.XMLHttpRequest(); 
    //Upload progress 
    xhr.upload.addEventListener("progress", function(evt){ 
     if (evt.lengthComputable) { 
     var percentComplete = evt.loaded/evt.total; 
     console.log("Upload ", Math.round(percentComplete*100) + "% complete."); 
     } 
    }, false); 
    return xhr; 
    }, 
    type: 'POST', 
    url: "/echo/json/", 
    data: {json: JSON.stringify(new Array(200000))} 
}); 

Ensuite, vous obtenez la progression normale des événements progress:

Upload 8% complete. 
Upload 9% complete. 
Upload 19% complete. 
Upload 39% complete. 
Upload 50% complete. 
Upload 81% complete. 
Upload 85% complete. 
Upload 89% complete. 
Upload 100% complete. 

Ce comportement dépend de la rapidité de votre connexion Internet est, de sorte que votre kilométrage varie. Par exemple, si vous prenez le premier exemple et que vous utilisez les outils de développement Chrome pour ralentir votre connexion à une simulation "Slow 3G", vous verrez la série d'événements progress. De même, si vous développez localement et téléchargez des données sur un serveur Web local, vous ne verrez probablement jamais d'événements progress car le téléchargement se terminera instantanément. C'est probablement ce que @brettjonesdev voyait dans les déploiements localhost vs prod.

Questions connexes