XHR上传进度从一开始就是100%

Ben*_*son 22 javascript ajax xmlhttprequest

我正在尝试新的XMLHTTPRequestUpload功能将一些文件上传到php脚本,它大部分工作正常,上传开始,我得到完成响应等 - 但进展似乎不起作用.

看看event.loaded值 - 在firefox中,我似乎得到一个介于0和文件大小之间的随机值; 在Chrome(我主要工作的地方)我得到了总文件大小,即使readystate没有达到'4'并且Developer Tools窗口仍显示要加载的文件?

有任何想法吗?

继承我的代码:

var xhr = new XMLHttpRequest()

xhr.upload.addEventListener('progress', function(event) {
    if (event.lengthComputable) {
        $('ajaxFeedbackDiv').innerHTML = event.loaded + ' / ' + event.total;
    }
}, false);

xhr.onreadystatechange = function(event) {
    if (event.target.readyState == 4) {
        updateFileList();
    }
};

xhr.open("POST", "_code/upload.php");
xhr.setRequestHeader("Cache-Control", "no-cache");
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.setRequestHeader("X-File-Size", file.size);
xhr.setRequestHeader("X-File-Type", file.type);
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr(file);
Run Code Online (Sandbox Code Playgroud)

非常感谢

本

R H*_*ill 20

我最近也为XHR onprogress事件设置事件监听器有些困难.我最终将它作为一个匿名函数实现,它可以很好地工作:

xhr.upload.onprogress = function(evt)
{
    if (evt.lengthComputable)
    {
        var percentComplete = parseInt((evt.loaded / evt.total) * 100);
        console.log("Upload: " + percentComplete + "% complete")
    }
};
Run Code Online (Sandbox Code Playgroud)

不过,我偶然发现了很多其他陷阱,所以很可能其中一个是绊倒了我的事件监听器.你所拥有的和我的设置之间的唯一区别是我正在使用xhr.sendAsBinary().


小智 6

我有类似的问题,我找到了原因。就我而言,麻烦制造者是我电脑上的防病毒软件(bitdefender)。当我关闭 bitdefender 保护时,进度表现完全符合预期。


Ell*_* B. 5

我遇到了一个类似的问题我自己,我的事件处理函数progress的事件XMLHttpRequest只执行一次-上载完成时。

问题的原因最终很简单-在Google Chrome浏览器中(可能还有其他浏览器,我没有测试过),该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))}
});
Run Code Online (Sandbox Code Playgroud)

控制台输出:

Upload  100% complete.
Run Code Online (Sandbox Code Playgroud)

但是,如果您向数组的大小添加一个额外的零(将有效负载大小增加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))}
});
Run Code Online (Sandbox Code Playgroud)

然后,您得到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.
Run Code Online (Sandbox Code Playgroud)

此行为取决于您的Internet连接速度,因此您的里程会有所不同。例如,如果您以第一个示例为例,并使用Chrome开发者工具来降低与模拟“慢速3G”的连接速度,那么您将看到一系列progress事件。

同样,如果您正在本地进行开发并将数据上传到本地Web服务器,则您将永远不会看到progress事件,因为上传将立即完成。这可能是@brettjonesdev在localhost与远程产品部署中看到的。