title: How can I use deflated/gzipped content with an XHR onProgress function?
body: <p>I've seen a bunch of similar questions to this get asked before, but I haven't found one that describes my current problem exactly, so here goes:</p>
  
  <p>I have a page which loads a large (between 0.5 and 10 MB) JSON document via AJAX so that the client-side code can process it. Once the file is loaded, I don't have any problems that I don't expect. However, it takes a long time to download, so I tried leveraging the <a href="https://dvcs.w3.org/hg/progress/raw-file/tip/Overview.html" rel="noreferrer">XHR Progress API</a> to render a progress bar to indicate to the user that the document is loading. This worked well.</p>
  
  <p>Then, in an effort to speed things up, I tried compressing the output on the server side via gzip and deflate. This worked too, with tremendous gains, however, my progress bar stopped working.</p>
  
  <p>I've looked into the issue for a while and found that if a proper <code>Content-Length</code> header isn't sent with the requested AJAX resource, the <code>onProgress</code> event handler cannot function as intended because it doesn't know how far along in the download it is. When this happens, a property called <code>lengthComputable</code> is set to <code>false</code> on the event object.</p>
  
  <p>This made sense, so I tried setting the header explicitly with both the uncompressed and the compressed length of the output. I can verify that the header is being sent, and I can verify that my browser knows how to decompress the content. But the <code>onProgress</code> handler still reports <code>lengthComputable = false</code>.</p>
  
  <p>So my question is: <strong>is there a way to gzipped/deflated content with the AJAX Progress API?</strong> And if so, what am I doing wrong right now?</p>
  
  <hr>
  
  <p>This is how the resource appears in the Chrome Network panel, showing that compression is working:</p>
  
  <p><a href="https://i.stack.imgur.com/b5yoY.png" rel="noreferrer"><img src="https://i.stack.imgur.com/b5yoY.png" alt="network panel"></a></p>
  
  <p>These are the relevant <strong>request</strong> headers, showing that the request is AJAX and that <code>Accept-Encoding</code> is set properly:</p>
  
  <pre class="lang-none prettyprint-override"><code>GET /dashboard/reports/ajax/load HTTP/1.1
  Connection: keep-alive
  Cache-Control: no-cache
  Pragma: no-cache
  Accept: application/json, text/javascript, */*; q=0.01
  X-Requested-With: XMLHttpRequest
  User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.99 Safari/537.22
  Accept-Encoding: gzip,deflate,sdch
  Accept-Language: en-US,en;q=0.8
  Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
  </code></pre>
  
  <p>These are the relevant <strong>response</strong> headers, showing that the <code>Content-Length</code> and <code>Content-Type</code> are being set correctly:</p>
  
  <pre class="lang-none prettyprint-override"><code>HTTP/1.1 200 OK
  Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
  Content-Encoding: deflate
  Content-Type: application/json
  Date: Tue, 26 Feb 2013 18:59:07 GMT
  Expires: Thu, 19 Nov 1981 08:52:00 GMT
  P3P: CP="CAO PSA OUR"
  Pragma: no-cache
  Server: Apache/2.2.8 (Unix) mod_ssl/2.2.8 OpenSSL/0.9.8g PHP/5.4.7
  X-Powered-By: PHP/5.4.7
  Content-Length: 223879
  Connection: keep-alive
  </code></pre>
  
  <p>For what it's worth, I've tried this on both a standard (http) and secure (https) connection, with no differences: the content loads fine in the browser, but isn't processed by the Progress API.</p>
  
  <hr>
  
  <p>Per <a href="https://stackoverflow.com/a/15172401/350278">Adam's suggestion</a>, I tried switching the server side to gzip encoding with no success or change. Here are the relevant response headers:</p>
  
  <pre class="lang-none prettyprint-override"><code>HTTP/1.1 200 OK
  Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
  Content-Encoding: gzip
  Content-Type: application/json
  Date: Mon, 04 Mar 2013 22:33:19 GMT
  Expires: Thu, 19 Nov 1981 08:52:00 GMT
  P3P: CP="CAO PSA OUR"
  Pragma: no-cache
  Server: Apache/2.2.8 (Unix) mod_ssl/2.2.8 OpenSSL/0.9.8g PHP/5.4.7
  X-Powered-By: PHP/5.4.7
  Content-Length: 28250
  Connection: keep-alive
  </code></pre>
  
  <p>Just to repeat: the content is being downloaded and decoded properly, it's just the progress API that I'm having trouble with.</p>
  
  <hr>
  
  <p>Per <a href="https://stackoverflow.com/questions/15097712/how-can-i-use-deflated-gzipped-content-with-an-xhr-onprogress-function?noredirect=1#comment21565866_15097712">Bertrand's request</a>, here's the request:</p>
  
  <pre><code>$.ajax({
      url: '&lt;url snipped&gt;',
      data: {},
      success: onDone,
      dataType: 'json',
      cache: true,
      progress: onProgress || function(){}
  });
  </code></pre>
  
  <p>And here's the <code>onProgress</code> event handler I'm using (it's not too crazy):</p>
  
  <pre><code>function(jqXHR, evt)
  {
      // yes, I know this generates Infinity sometimes
      var pct = 100 * evt.position / evt.total;
  
      // just a method that updates some styles and javascript
      updateProgress(pct);
  });
  </code></pre>