压缩内容的 XMLHttpRequest 进度事件问题(FireFox 除外)

1cg*_*nza 4 javascript json google-chrome xmlhttprequest progress-bar

在我的应用程序中,我使用 API 请求大型 JSON 文件XMLHttpRequest。这按预期工作。

我想在用户等待时显示进度条。一些 JSON 文件大小在 6 到 10 Mb 以上,因此进度条将有助于改善整体体验。

这是我正在做的事情的一个例子:

var progress = document.getElementById('progress');

function getData(url) {
    var req = new XMLHttpRequest();

  req.onprogress = function(event) {
    if (event.lengthComputable) {
      progress.value = event.loaded / event.total * 100;
    } else {
      console.log('lengthComputable failed');
    }
  }

  req.onload = function() {
    console.log('Finished loading');
    // ... handle data
  }

  req.open('GET', url, true);
  req.overrideMimeType('application/json');
  req.send(null);
}

getData('https://raw.githubusercontent.com/datasets/geo-countries/master/data/countries.geojson');
Run Code Online (Sandbox Code Playgroud)

另外在 jsfiddle 上: https: //jsfiddle.net/ctL5f73s/1/

如果内容未经过 gzip 压缩,则进度条似乎在我迄今为止测试过的所有浏览器上都能正常工作。但如果服务器将其作为 gzip 发送,则只有 Firefox 可以工作。

作为上下文,我正在从 GitHub 请求数据。我的理解是,他们将所有资产作为 gzip 提供,我无法控制它。

我还知道XHR 的进度事件应该处理 gzipped 内容。他们所说的大部分内容都在我的脑海中浮现,但我收集到的是,没有计划改变lengthComputable内容压缩时的处理方式。

Response Headers我看到的Content-EncodingContent-Length是正确的:

在此输入图像描述

问题是:有什么方法可以使进度事件在 FireFox 以外的浏览器上使用 gzip 内容吗?

如果不可能,任何人都可以指出我的替代方案吗?最好是原生 JS 而不是库。

我不介意太早的兼容性,但如果它不能与最新版本的 Chrome 兼容,那就是一个问题。

小智 6

我做了这样的事情。这并不准确,但已经足够好了。

req.onprogress = function(event) {
  if (event.lengthComputable) {
    progress.value = event.loaded / event.total * 100
  } else {
    var total = req.getResponseHeader('content-length')
    var encoding = req.getResponseHeader('content-encoding')
    if (total && encoding && (encoding.indexOf('gzip') > -1)) {
      // assuming average gzip compression ratio to be 25%
      total *= 4 // original size / compressed size
      progress.value = Math.min(100, event.loaded / total * 100)
    } else {
      console.log('lengthComputable failed')
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

显然,有时进度会跳到 100%,有时会停留在 100%,但只持续很短的一段时间,所以很难被注意到。