javascript 为什么 XMLHttpRequest ProgressEvent.lengthComputable 可能是假的?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10956574/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why might XMLHttpRequest ProgressEvent.lengthComputable be false?
提问by Dave
I'm trying to implement a upload progress bar the HTML5 way, by using the XMLHttpRequest level 2 support for progress events.
我正在尝试通过对进度事件使用 XMLHttpRequest 级别 2 支持,以 HTML5 方式实现上传进度条。
In every example you see, the method is to add an event listener to the progress event like so:
在您看到的每个示例中,方法是向进度事件添加一个事件侦听器,如下所示:
req.addEventListener("progress", function(event) {
if (event.lengthComputable) {
var percentComplete = Math.round(event.loaded * 100 / event.total);
console.log(percentComplete);
}
}, false);
Such examples always seem to assume that event.lengthComputable will be true. After all, the browser knows the length of the request it's sending, surely?
这样的例子似乎总是假设 event.lengthComputable 为真。毕竟,浏览器肯定知道它发送的请求的长度吗?
No matter what I do, event.lengthComputable is false. I've tested this in Safari 5.1.7 and Firefox 12, both on OSX.
不管我做什么, event.lengthComputable 都是假的。我已经在 OSX 上的 Safari 5.1.7 和 Firefox 12 中对此进行了测试。
My site is built using Django, and I get the same problem on my dev and production setups.
我的网站是使用 Django 构建的,我的开发和生产设置也遇到了同样的问题。
The full code I'm using to generate the form upload is shown below (using jQuery):
我用来生成表单上传的完整代码如下所示(使用 jQuery):
form.submit(function() {
// Compile the data.
var data = form.serializeArray();
data.splice(0, 0, {
name: "file",
value: form.find("#id_file").get(0).files[0]
});
// Create the form data.
var fd = new FormData();
$.each(data, function(_, item) {
fd.append(item.name, item.value);
});
// Submit the data.
var req = new XMLHttpRequest();
req.addEventListener("progress", function(event) {
if (event.lengthComputable) {
var percentComplete = Math.round(event.loaded * 100 / event.total);
console.log(percentComplete);
}
}, false);
req.addEventListener("load", function(event) {
if (req.status == 200) {
var data = $.parseJSON(event.target.responseText);
if (data.success) {
console.log("It worked!")
} else {
console.log("It failed!")
}
} else {
console.log("It went really wrong!")
}
}, false);
req.addEventListener("error", function() {
console.log("It went really really wrong!")
}, false);
req.open("POST", "/my-bar/media/add/");
req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
req.send(fd);
// Don't really submit!
return false;
});
I've been tearing my hair out for hours on this. Any help appreciated!
我已经为此扯了几个小时的头发。任何帮助表示赞赏!
回答by est
Hey I found the answerfrom @ComFreek:
嘿,我从@ComFreek找到了答案:
I made the same mistake.
我犯了同样的错误。
The line I wrote was:
我写的那一行是:
xhr.onprogress = uploadProgress;
The correct one should be
正确的应该是
xhr.upload.onprogress = uploadProgress;
回答by CSStudent
take a look into this : https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications
看看这个:https: //developer.mozilla.org/en-US/docs/Using_files_from_web_applications
xhr.upload.addEventListener('progress',function(e){}) will also work.
xhr.upload.addEventListener('progress',function(e){}) 也可以工作。
回答by wowkin2
I also had problem with sending multiple big files using AJAX (xmlhttprequest).
我也有使用 AJAX (xmlhttprequest) 发送多个大文件的问题。
Found a solution and here is whole script that I use. All you need is to place next line in your HTML page:
找到了一个解决方案,这里是我使用的整个脚本。您只需要在 HTML 页面中放置下一行:
<input type="file" multiple name="file" id="upload_file" onchange="handleFiles(this)">
and use next script:
并使用下一个脚本:
<script type="text/javacript">
var filesArray;
function sendFile(file)
{
var uri = "<URL TO PHP FILE>";
var xhr = new XMLHttpRequest();
var fd = new FormData();
var self = this;
xhr.upload.onprogress = updateProgress;
xhr.addEventListener("load", transferComplete, false);
xhr.addEventListener("error", transferFailed, false);
xhr.addEventListener("abort", transferCanceled, false);
xhr.open("POST", uri, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText); // handle response.
}
};
fd.append('myFile', file);
// Initiate a multipart/form-data upload
xhr.send(fd);
}
function updateProgress (oEvent)
{
if (oEvent.lengthComputable)
{
var percentComplete = oEvent.loaded / oEvent.total;
console.log(Math.round(percentComplete*100) + "%");
} else {
// Unable to compute progress information since the total size is unknown
console.log("Total size is unknown...");
}
}
function transferComplete(evt)
{
alert("The transfer is complete.");
}
function transferFailed(evt)
{
alert("An error occurred while transferring the file.");
}
function transferCanceled(evt)
{
alert("The transfer has been canceled by the user.");
}
function handleFiles(element)
{
filesArray = element.files;
if (filesArray.length > 0)
{
for (var i=0; i<filesArray.length; i++)
{
sendFile(filesArray[i]);
}
filesArray = '';
}
}
</script>
Your result will be in console
您的结果将在控制台中