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

问题描述 投票:2回答:2

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

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

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

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

同样在jsfiddle:https://jsfiddle.net/ctL5f73s/1/

如果内容没有被gzip压缩,那么进度条似乎在我到目前为止测试的所有浏览器上都能正常工作。但是如果服务器将其作为gzip发送,则只有firefox有效。

对于上下文,我从GitHub请求数据。我的理解是他们将所有资产都用作gzip,我无法控制它。

我也知道XHR's progress events should handle gzipped content。他们说的大部分内容都飞到了我的头上,但我收集到的是,当内容被压缩时,没有计划改变lengthComputable的处理方式。

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

enter image description here

问题是:有没有办法让进度事件在FireFox以外的浏览器上使用gzip内容?

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

我不介意兼容​​性太远,但如果它不适用于最新版本的Chrome,那么这是一个问题。

javascript json google-chrome xmlhttprequest progress-bar
2个回答
4
投票

我做了这样的事。这不是确切的,但它已经足够了。

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')
    }
  }
}

很明显,有时候进度会上升到100%,有时它会停留在100%,但只是短暂的一小时,所以它几乎不会引起注意。


0
投票

问题可能是您的Content-Type:text / plain。在shell命令行使用curl来获取GET(没有 - 压缩,立即看到二进制输出) - 响应是否立即显示?

例如,Chrome没有立即为'text / plain'命中onprogress回调,但是如果你使用'application / json'就行了。在您的响应标头中尝试'Content-Type:application / json',看看是否有所作为。

© www.soinside.com 2019 - 2024. All rights reserved.