谷歌浏览器中的XMLHttpRequest没有报告进度事件

17

大家好,我有这段代码:

function test()
{
    req = new XMLHttpRequest();
    req.upload.addEventListener("progress", updateProgress, false);
    req.addEventListener("readystatechange", updateProgress, false);
    req.addEventListener("error", uploadFailed, false);
    req.addEventListener("abort", uploadCanceled, false);

    var data = generateRandomData(currentPayloadId);
    totalSize = data.length;

    req.open("POST", "www.mydomain.com/upload.aspx");
    start = (new Date()).getTime();
    req.send(data);
}

function updateProgress(evt)
{
    if (evt.lengthComputable) {
        total = totalSize = evt.total;
        loaded = evt.loaded;
    }
    else {
        total = loaded = totalSize;
    }
}

同时,我的服务器对于上传.aspx的初始OPTIONS请求做出200的响应,并添加Access-Control-Allow-Origin: *,然后发生第二个POST请求。

在FireFox上一切都很顺利,但在G Chrome上,updateProgress处理程序仅被调用一次,然后lengthComputable为false。

我需要Access-Control-Allow-Origin: *,因为这是一个跨域调用,脚本父级资源与upload.aspx域不同步。

有人可以给我一些线索、提示或帮助吗?这是G Chrome已知的问题吗?

谢谢! Ova


1
如果不是CORS,这个能工作吗?如果可以的话,请在http://crbug.com/new上报告一个错误。 - Kinlan
对于正在寻找答案的人,如果xhr进度事件将evt.lengthComputable设置为false,则可以完全跳过func updateProgress的eval体。我不太确定是什么决定了这种行为,但它似乎发生在请求中的单块小交换中。您可以通过检查事件处理程序的positionloaded属性(仅)轻松检查{在同一函数中}完成情况。 (顺便说一句,这种语法可能与最新版本的jquery不兼容。) - Cristian Cavalli
1
由于您正在使用绝对URL,所以它不应该以“http://”开头吗? - Scott Marcus
我有类似的进度事件问题:https://stackoverflow.com/questions/48679979/xmlhttprequest-onprogress-event-function-has-different-behavior - sultan
5个回答

4

我想我对你的问题有一个解决方案
我不知道这个函数“generateRandomData()”背后的东西是什么

var data = generateRandomData(currentPayloadId)

当我改成这样时,它就可以工作了:

var data = new FormData();
data.append("fileToUpload", document.getElementById('fileToUpload').files[0]);

简短说明:您需要手动添加文件输入表单到表单数据中,其中fileToUpload<input type="file" name="fileToUpload" id="fileToUpload" />
并且在您的updateProgress函数的IF部分中,您可以添加类似于此的内容来跟踪进度:console.log(evt.total +" - "+ evt.loaded)
enter image description here

这在Google Chrome浏览器中有效。我已经在新的浏览器版本57中进行了测试
4年前我为自己制作了一个上传进度表单,这意味着这段代码也适用于旧版浏览器。

整个代码段将如下所示:

function test()
{
    req = new XMLHttpRequest();
    req.upload.addEventListener("progress", updateProgress, false);
    req.addEventListener("readystatechange", updateProgress, false);
    req.addEventListener("error", uploadFailed, false);
    req.addEventListener("abort", uploadCanceled, false);

    //var data = generateRandomData(currentPayloadId);
    var data = new FormData();
    data.append("fileToUpload", document.getElementById('fileToUpload').files[0]);
    totalSize = data.length;

    req.open("POST", "www.mydomain.com/upload.aspx");
    start = (new Date()).getTime();
    req.send(data);
}

function updateProgress(evt)
{
    if (evt.lengthComputable) {
        total = totalSize = evt.total;
        loaded = evt.loaded;
        console.log(evt.total +" - "+ evt.loaded)
    }
    else {
        total = loaded = totalSize;
    }
}

1
当你加载的页面不包含

标签时,就会出现这个问题。
  Content-Length: 12345

在头部,12345表示响应的字节数。如果没有长度参数,进度函数将无法工作。

0

0

这可能只是与XMLHttpRequest.upload属性的兼容性问题。它返回一个XMLHttpRequestUpload对象,但如果您尝试在MDN中查找该对象规范,则不存在,那么我们如何知道哪些浏览器完全支持它。

XMLHttpRequest.upload兼容性 XMLHttpRequest.upload属性的兼容性

您是否尝试直接在xhr上监听进度:

req.addEventListener("progress", updateProgress, false);

0

我使用jQuery来实现这样的进度条:

    $.ajax({
        url : furl,
        type : method,
        data : data,
        //...
        },
        xhr : function () {
            //upload Progress
            var xhr = $.ajaxSettings.xhr();
            if (xhr.upload) {
                    xhr.upload.addEventListener('progress', function (event) {
                        var percent = 0;
                        var position = event.loaded || event.position;
                        var total = event.total;
                        if (event.lengthComputable) {
                            percent = Math.ceil(position / total * 100);
                        }
                        //update progressbar
                        $(".progress-bar").css("width",  + percent + "%");
                        $(" .status").text(position + " / " + total + " (" + percent + "%)");
                    }, true);
            }
            return xhr;
        },

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接