google-chrome 中的 XMLHttpRequest 未报告进度事件

Posted

技术标签:

【中文标题】google-chrome 中的 XMLHttpRequest 未报告进度事件【英文标题】:XMLHttpRequest in google-chrome is not reporting progress events 【发布时间】:2012-02-07 17:24:59 【问题描述】:

大家好,我有这个代码:

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;
    

此外,我的服务器使用 200 和 Access-Control-Allow-Origin 响应对 upload.aspx 的初始 OPTIONS 请求:* 然后发生第二个请求 POST

一切似乎都已经到位,它在 FireFox 上运行良好,但在 G Chrome 上,updateProgress 处理程序没有被调用,而是只调用一次,然后 lengthComputable 为 false。

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

任何人都可以给我一些线索,提示,请帮助?这是 G Chrome 的已知问题吗?

谢谢! 卵子

【问题讨论】:

当它不是 CORS 时这是否有效?如果确实如此,则在 crbug.com/new 上引发错误 对于环顾四周的人,如果 xhr 进度事件已将 evt.lengthComputable 设置为 false,则可能会完全跳过 func updateProgress 的 eval 正文。我不太确定是什么决定了这种行为,但它似乎发生在请求中的一小块小交换中。您可以通过检查事件处理程序positionloaded 属性轻松检查在同一功能 完成(仅)。 (顺便说一句,这种语法(很可能)与 jquery 的最新迭代不兼容。) 既然使用的是绝对网址,不应该以“http://”开头吗? 我对进度事件有类似的问题:***.com/questions/48679979/… 【参考方案1】:

我想我有办法解决你的问题 我不知道这个函数“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" />IF 部分的updateProgress 函数中,您可以添加类似这样的内容来跟踪进度console.log(evt.total +" - "+ evt.loaded)

这适用于谷歌 Chrome 浏览器。我已经在新的浏览器版本 57 中进行了测试 我在 4 年前为自己制作了一个上传进度表,这意味着这段代码也可以在旧浏览器版本中运行。 整个代码 sn-p 会是这样的

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;
    

【讨论】:

【参考方案2】:

当您正在加载的页面不包含

时,我遇到了这个问题
  Content-Length: 12345

在标头中,其中 12345 是响应的长度(以字节为单位)。如果没有长度参数,进度函数就没有任何作用。

【讨论】:

【参考方案3】:

首先,确保将"www.example.com" 添加到manifest.json,如下所示:

ma​​nifest.json

 
   ..
   "permissions": [
     "http://www.example.com/",
     "https://www.example.com/",
   ],
   ..
 

那么我认为你的例子应该有效。

For more information about using xhr in google chrome extensions the docs are here.

如果我上面提供的内容没有,the CSP docs 也值得一看。

【讨论】:

【参考方案4】:

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

XMLHttpRequest.upload 兼容性

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

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

【讨论】:

【参考方案5】:

我使用 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;
        ,

【讨论】:

以上是关于google-chrome 中的 XMLHttpRequest 未报告进度事件的主要内容,如果未能解决你的问题,请参考以下文章

google-chrome 无法移动到新的命名空间

google-chrome的安装

在无头 debian 系统上通过 Selenium 启动 google-chrome

使用 `google-chrome --headless` 时如何设置浏览器窗口大小?

[Linux] CentOS 用源安装 Google-Chrome 浏览器

centos7安装google-chrome和chromedriver