0

我想使用 XHR 对象的“进度”事件来获取下载进度。

这是来自MDN的示例代码

var req = new XMLHttpRequest();

req.addEventListener("progress", updateProgress, false);
req.addEventListener("load", transferComplete, false);
req.addEventListener("error", transferFailed, false);
req.addEventListener("abort", transferCanceled, false);

req.open();

...

// progress on transfers from the server to the client (downloads)
function updateProgress(evt) {
  if (evt.lengthComputable) {
    var percentComplete = evt.loaded / evt.total;
    ...
  } else {
    // Unable to compute progress information since the 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.");
}

我写过类似的代码,但lengthComputable进度事件的字段结果是错误的。该loaded字段是某个有限值,但total设置为零。

从上面代码示例中的注释中,我可以看到浏览器在 HTTP 响应中没有获得足够的信息来计算有意义的下载进度。

编写响应以使其工作的正确方法是什么?我在测试中看到的响应有Transfer-encoding: chunkedContent-Length: 8。我从 Tornado Web 服务器生成它。

4

1 回答 1

3

分块传输编码中,响应的总长度不由服务器指示,因此客户端事先不知道。

你可以尝试两件事。

  • 要么禁用分块传输编码,而是使用Content-Length. 这是进度事件规范所要求的。但我不知道 Tornado 是否/如何做到这一点。
  • 或者,在自定义响应标头中包含总长度,例如X-Total-Length. 然后,使用这样的代码来确定你的百分比:

    function updateProgress(evt) {
      var total = evt.lengthComputable ?
                  evt.total : parseInt(req.getResponseHeader('X-Total-Length'));
      if (total) {
        var percentComplete = evt.loaded / total;
        // ...
      }
    }
    
于 2012-06-27T08:32:13.947 回答