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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 11:37:00  来源:igfitidea点击:

Why might XMLHttpRequest ProgressEvent.lengthComputable be false?

javascriptajaxxmlhttprequest

提问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

您的结果将在控制台中