【问题标题】:XHR Upload Progress is 100% from the startXHR 上传进度从一开始就是 100%
【发布时间】:2011-03-22 02:53:58
【问题描述】:

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

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

有什么想法吗?

这是我的代码:

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);

非常感谢

【问题讨论】:

  • 您是否找到任何解决方案或解决方法?我目前遇到同样的情况,但这似乎取决于您的网络连接。它在一个位置按预期工作,从另一个位置跳到 100%。
  • 我遇到了同样的问题。有趣的是,这似乎只发生在我在本地主机上运行时 - 当我部署到我们的开发或生产服务器时,加载的值会如预期的那样返回。
  • XHR 上传进度从一开始就 100% 仅在本地主机上(我不知道为什么),如果您尝试向远程 Web 服务器或远程服务器发出请求,您会看到明智的进展。

标签: javascript ajax xmlhttprequest


【解决方案1】:

我有类似的问题,我找到了原因。就我而言,麻烦制造者是我 PC 上的防病毒软件 (bitdefender)。当我关闭 bitdefender 保护时,进度的行为完全正常。

【讨论】:

  • 谢谢约翰,我到处搜索...有时我讨厌 BitDefender...只是显示它拦截了多少数据!
  • 在我们的案例中,Bitdefender Web Protection 选项导致了问题。
【解决方案2】:

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

问题的原因很简单——在谷歌浏览器(可能还有其他浏览器,我没有测试)中,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))}
});

控制台输出:

Upload  100% complete.

但是如果你在数组的大小上添加一个额外的零(将有效负载大小增加 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))}
});

然后你得到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.

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

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

【讨论】:

  • 我在发送 FormData 时仍然遇到这个问题,并且限制了 Chrome 的上传速度。上传最多需要一分钟,最后只会发出一个事件。有什么想法吗?
【解决方案3】:

我最近在为 XHR onprogress 事件设置事件侦听器时也遇到了一些困难。我最终将它实现为一个匿名函数,效果很好:

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

不过,我在此过程中偶然发现了 很多 其他陷阱,因此很可能其中一个让我的事件侦听器绊倒了。您所拥有的与我的设置之间的唯一其他区别是我使用的是 xhr.sendAsBinary()。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-04
    • 2016-08-11
    • 1970-01-01
    • 1970-01-01
    • 2021-05-21
    • 2019-03-22
    • 2012-09-24
    相关资源
    最近更新 更多