我之前看到过很多与此类似的问题,但我还没有找到一个准确描述我当前问题的问题,所以这里是:
我有一个通过 AJAX 加载大型(0.5 到 10 MB 之间)JSON 文档的页面,以便客户端代码可以处理它。加载文件后,我不会遇到任何我没想到的问题。但是,下载需要很长时间,因此我尝试利用XHR Progress API呈现进度条,以向用户指示文档正在加载。这运作良好。
然后,为了加快速度,我尝试通过 gzip 和 deflate 压缩服务器端的输出。这也有效,取得了巨大的收益,但是,我的进度条停止工作。
我已经研究了一段时间,发现如果Content-Length
没有与请求的 AJAX 资源一起发送正确的标头,则onProgress
事件处理程序无法按预期运行,因为它不知道下载的进度。发生这种情况时,将在事件对象上lengthComputable
设置一个名为的属性。false
这是有道理的,所以我尝试使用输出的未压缩和压缩长度显式设置标头。我可以验证是否正在发送标头,并且可以验证我的浏览器是否知道如何解压缩内容。但onProgress
处理程序仍然报告lengthComputable = false
。
所以我的问题是:有没有办法使用 AJAX Progress API 压缩/压缩内容?如果是这样,我现在做错了什么?
这是资源在 Chrome 网络面板中的显示方式,表明压缩正在工作:
这些是相关的请求标头,表明请求是 AJAX 并且Accept-Encoding
设置正确:
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
这些是相关的响应标头,表明Content-Length
和Content-Type
设置正确:
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
对于它的价值,我在标准 (http) 和安全 (https) 连接上都试过了,没有任何区别:内容在浏览器中加载良好,但没有被 Progress API 处理。
根据亚当的建议,我尝试将服务器端切换为 gzip 编码,但没有成功或更改。以下是相关的响应标头:
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
重复一遍:内容正在被正确下载和解码,这只是我遇到问题的进度 API。
根据Bertrand 的请求,请求如下:
$.ajax({
url: '<url snipped>',
data: {},
success: onDone,
dataType: 'json',
cache: true,
progress: onProgress || function(){}
});
这是onProgress
我正在使用的事件处理程序(这不是太疯狂):
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);
});