Note that there are some explanatory texts on larger screens.

plurals
  1. POHow can I use deflated/gzipped content with an XHR onProgress function?
    text
    copied!<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>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload