为什么 ProgressEvent.lengthComputable 为假?

2022-01-15 00:00:00 xmlhttprequest javascript

我正在 Google Chrome、Safari 和 Firefox 中使用 XMLHttpRequest 加载 JSON 文件.在所有三个浏览器中,我都收到了正确显示 .loaded 属性的 ProgressEvent.但是,.lengthComputable 属性为 false,.total 属性为零.我检查了 Content-Length HTTP 标头是否正在发送并且是正确的——它是正确的.响应正在被 gzip 编码,但 Content-length 正确显示了编码长度(解压缩前).

I am loading a JSON file using XMLHttpRequest in Google Chrome, Safari and Firefox. In all three browsers I am receiving ProgressEvents which correctly show the .loaded property. However the .lengthComputable property is false and the .total property is zero. I have checked that the Content-Length HTTP header is being sent and is correct - it is. The response is being gzip-encoded, but the Content-length correctly shows the encoded length (before decompression).

为什么总长度在我的ProgressEvents 中不可用?

Why would the total length not be available in my ProgressEvents?

这是标题:

HTTP/1.1 200 OK
ETag: "hKXdZA"
Date: Wed, 20 Jun 2012 20:17:17 GMT
Expires: Wed, 20 Jun 2012 20:17:17 GMT
Cache-Control: private, max-age=3600
X-AppEngine-Estimated-CPM-US-Dollars: $0.000108
X-AppEngine-Resource-Usage: ms=2 cpu_ms=0 api_cpu_ms=0
Content-Type: application/json
Content-Encoding: gzip
Server: Google Frontend
Content-Length: 621606

注意:该文件是通过 Google App Engine 提供的.

Note: the file is being served via Google App Engine.

这里是 JavaScript:

Here is the JavaScript:

var req;
if (window.XMLHttpRequest){
    req = new XMLHttpRequest();
    if(req.overrideMimeType){
        req.overrideMimeType( "text/json" );
    }
}else{
    req = new ActiveXObject('Microsoft.XMLHTTP');
}

// Listen for progress events
req.addEventListener("progress", function (event) {
    console.log(event, event.lengthComputable, event.total);
    if (event.lengthComputable) {
        self.progress = event.loaded / event.total;
    } else if (this.explicitTotal) {
        self.progress = Math.min(1, event.loaded / self.explicitTotal);
    } else {
        self.progress = 0;
    }
    self.dispatchEvent(Breel.Asset.ON_PROGRESS);
}, false);

req.open('GET', this.url);

注意:该代码中的 console.log 显示数百个具有最新 .loaded 的事件,但 .lengthComputable 始终是false 并且 .total 始终为零.self 指的是负责这个 XMLHttpRequest 的对象.

Note: The console.log in that code is showing hundreds of events with up to date .loadeds but .lengthComputable is always false and .total is always zero. self refers to the object responsible for this XMLHttpRequest.

推荐答案

如果 XMLHttpRequestProgressEvent 中的 lengthComputable 为 false,则意味着服务器从未在响应中发送 Content-Length 标头.

If lengthComputable is false within the XMLHttpRequestProgressEvent, that means the server never sent a Content-Length header in the response.

如果您使用 nginx 作为代理服务器,这可能是罪魁祸首,尤其是如果它没有将上游服务器的 Content-Length 标头通过代理服务器传递到浏览器.

If you're using nginx as a proxy server, this might be the culprit, especially if it's not passing the Content-Length header from the upstream server through the proxy server to the browser.

相关文章