2013-03-19 193 views
4

我在使上傳進度欄正常工作時遇到了一些問題。JS ProgressEvent僅在完成時觸發

按照XMLHttpRequest的2級規格,我附加事件偵聽器loadstart和進步是這樣的:

var xhr = $.ajaxSettings.xhr(); 
xhr.upload.addEventListener('loadstart', function(e) {progressCallback(0);}); 
xhr.upload.addEventListener('progress', function (e) { 
    progressCallback(e.loaded/e.total); 
});  

$.ajax({ 
    url: url, 
    type: 'POST', 
    processData: false, 
    contentType: false, 
    data: formData, 
    xhr: function() { 
     return xhr; 
    } 
}).done(function (data) { 
    // Finish stuff 
}) 

該文件正確上傳,但一旦請求與100%finsished進展監聽器只叫(e.total == e.loaded)

上面的代碼是否有問題,或者是否需要以任何特殊方式配置服務器?

回答

2

當無法確定文件的總大小時,e.loadede.total爲零。您可以檢查此您progress函數中:

if (evt.lengthComputable) { 
    progressCallback(e.loaded/e.total); 
} 

服務器還必須發送Content-Length這是在specification定義:

如果HTTP實體主體的長度是通過內容長度已知頭,將lengthComputable屬性初始化爲true,並將總屬性初始化爲長度。

另請注意,進度欄不適用於file:協議。

我真的可以推薦Mozilla的文檔,這是非常廣泛 - Using XMLHTTPRequest Mozilla Docs

+0

謝謝!我會看看這個! – 2013-03-19 10:30:37

+0

服務器是否必須傳遞一些東西,以使lengthComputable成爲true? 因爲我已經正確發送的Content-Length ... – 2013-03-19 11:31:05

+0

http://stackoverflow.com/questions/11127654/why-is-progressevent-lengthcomputable-false。服務器也必須發送'Content-Length'。 – Eich 2013-03-19 11:35:04

0

我遇到類似的問題我自己,在這裏只執行一次,我對progress事件的事件處理函數上XMLHttpRequest - 上傳完成時。

結束了簡單的問題的原因 - (可能是其他瀏覽器也一樣,我沒有測試)在谷歌瀏覽器,該progress事件將導致上載已經運行了一兩秒鐘,只陸續火災。換句話說,如果您的上傳速度很快,那麼您很可能會收到一個100%的事件。

這裏是代碼的例子,其progress事件僅在100%完成(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))} 
}); 

控制檯輸出:

Upload 100% complete. 

但是,如果你添加一個額外零大小(增加有效載荷大小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))} 
}); 

然後你得到的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. 

此行爲取決於您的Internet連接速度有多快,所以你的里程可能會有所不同。例如,如果您拿第一個示例並使用Chrome開發人員工具減慢與模擬「慢速3G」的連接,那麼您將看到一系列progress事件。

同樣,如果您是在本地和上傳數據發展到本地Web服務器,你可能永遠也看不到progress事件,因爲上傳將立即結束。

相關問題