Why is ProgressEvent.lengthComputable false?

javascript, xmlhttprequest

Solution

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

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.

Problem

I am loading a JSON file using XMLHttpRequest in Google Chrome, Safari and Firefox. In all three browsers I am receiving `ProgressEvent`s 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). Why would the total length not be available in my `ProgressEvent`s? Here are the headers: ``` 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 ``` Note: the file is being served via Google App Engine. 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); ``` Note: The `console.log` in that code is showing hundreds of events with up to date `.loaded`s but `.lengthComputable` is always false and `.total` is always zero. `self` refers to the object responsible for this `XMLHttpRequest`.

Original source