[英]XMLHttpRequest event onProgress is being fired only when file has finished upload
[英]JS ProgressEvent is only fired when finished
我在上传进度条正常工作时遇到了一些问题。
根据XMLHttpRequest Level 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%完成后才会调用进度监听器(e.total == e.loaded)
上面的代码有什么问题,或者是否有必要以任何特殊方式配置服务器?
当无法确定文件的总大小时, e.loaded
和e.total
为零。 你可以在progress
函数中检查这个:
if (evt.lengthComputable) {
progressCallback(e.loaded / e.total);
}
服务器还必须发送规范中定义的Content-Length
:
如果通过Content-Length标头知道HTTP实体主体的长度,则将lengthComputable属性初始化为true,并将total属性初始化为length。
另请注意,进度条不适用于file:
protocol。
我真的可以推荐非常广泛的Mozilla文档 - 使用XMLHTTPRequest Mozilla文档
我自己遇到了类似的问题,我在XMLHttpRequest
上的progress
事件的事件处理函数只执行了一次 - 当上传完成时。
问题的原因最终变得简单 - 在谷歌浏览器(可能还有其他浏览器,我没有测试),如果上传已经运行了一两秒, progress
事件将只会连续触发。 换句话说,如果您的上传速度很快,那么您可能只会获得一次100%的progress
事件。
这是一个代码示例,其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
事件,因为上传将立即完成。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.