2010-07-28 7 views
16

Ich probiere die neue XMLHTTPRequestUpload-Funktion aus, um einige Dateien in ein PHP-Skript hochzuladen, es funktioniert meistens gut, der Upload startet, ich bekomme die Antwort usw. - aber der Fortschritt geht nicht Es scheint nicht zu funktionieren.XHR-Upload-Fortschritt ist 100% von Anfang an

Suche nach dem event.loaded Wert - In Firefox scheint ich einen zufälligen Wert zwischen 0 und der Dateigröße zu erhalten; In Chrome (wo ich hauptsächlich arbeite) bekomme ich die Gesamtgröße der Datei, obwohl der Ready-Status noch nicht die '4' erreicht hat und das Developer Tools-Fenster weiterhin die zu ladende Datei anzeigt?

Irgendwelche Ideen?

Heres mein 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); 

Vielen Dank

Ben

+0

Haben Sie eine Lösung oder eine Problemumgehung für das Problem gefunden? Ich erlebe derzeit das gleiche, aber es scheint abhängig von Ihrer Netzwerkverbindung zu sein. Es funktioniert wie erwartet an einem Ort und springt zu 100% von dem anderen. – unclenorton

+3

Ich habe das gleiche Problem. Interessanterweise scheint dies nur bei mir zu passieren, wenn ich auf localhost laufe - wenn ich auf unseren dev- oder prod-Servern deploye, kommt der geladene Wert zurück, wie man es erwarten würde. – brettjonesdev

Antwort

16

Ich hatte auch vor kurzem einige Schwierigkeiten ein Ereignis-Listener für XHR OnProgress Ereignisse einstellen. Ich landete es als eine anonyme Funktion implementiert, die schön funktioniert:

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

ich auf einem auf dem Weg anderen gotchas viel stolperte, obwohl, so ist es sehr wahrscheinlich, einer von denen war Auslösung meiner Event-Listener up . Der einzige andere Unterschied zwischen dem, was Sie dort haben, und meinem Setup ist, dass ich xhr.sendAsBinary() verwende.

0

Ich selbst stieß auf ein ähnliches Problem, wo meine Event-Handler-Funktion für progress Ereignisse auf XMLHttpRequest wurde nur einmal ausgeführt - wenn der Upload abgeschlossen war.

Die Ursache des Problems endete einfach - in Google Chrome (möglicherweise auch andere Browser habe ich nicht getestet), wird das Ereignis progress nur nacheinander ausgelöst, wenn der Upload für ein oder zwei Sekunden ausgeführt wurde. Mit anderen Worten, wenn Ihr Upload schnell beendet wird, erhalten Sie wahrscheinlich nur einen 100% progress Event.

Hier ist ein Beispiel von Code, dessen progress Ereignis nur einmal zu 100% abgeschlossen feuert (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))} 
}); 

Console Ausgabe:

Upload 100% complete. 

Aber wenn Sie eine zusätzliche Null auf die Größe hinzufügen des Arrays (Erhöhen der Nutzlastgröße um einen Faktor von 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))} 
}); 

Dann Sie den normalen Verlauf der progress Events:

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. 

Dieses Verhalten hängt davon ab, wie schnell Ihre Internetverbindung ist, so wird Ihre Laufleistung variieren. Wenn Sie beispielsweise das erste Beispiel verwenden und die Chrome-Entwicklertools verwenden, um die Verbindung zu einem simulierten "langsamen 3G" zu verlangsamen, werden Sie die Reihe der progress Ereignisse sehen.

Wenn Sie lokal arbeiten und Daten auf einen lokalen Webserver hochladen, werden Sie wahrscheinlich nie progress Ereignisse sehen, da der Upload sofort beendet wird. Dies ist wahrscheinlich das, was @brettjonesdev in localhost vs Remote Prod-Bereitstellungen sah.

Verwandte Themen