我之前见过很多类似的问题,但我还没有找到一个能够准确描述我当前问题的问题,所以这里是:
我有一个页面通过 AJAX 加载一个大的(0.5 到 10 MB 之间)JSON 文档,以便客户端代码可以处理它。加载文件后,我不会遇到任何意外的问题。但是下载需要很长时间,所以我尝试利用XHR进度API https://dvcs.w3.org/hg/progress/raw-file/tip/Overview.html呈现进度条以向用户指示文档正在加载。这很有效。
然后,为了加快速度,我尝试通过 gzip 和 deflate 压缩服务器端的输出。这也有效,取得了巨大的收益,但是,我的进度条停止了工作。
我已经研究这个问题一段时间了,发现如果正确的话Content-Length
标头未与请求的 AJAX 资源一起发送,onProgress
事件处理程序无法按预期运行,因为它不知道下载进度。当这种情况发生时,一个名为lengthComputable
被设定为false
在事件对象上。
这是有道理的,所以我尝试使用输出的未压缩和压缩长度显式设置标头。我可以验证标头是否正在发送,并且我可以验证我的浏览器是否知道如何解压缩内容。但是onProgress
处理程序仍然报告lengthComputable = false
.
所以我的问题是:有没有办法使用 AJAX Progress API 压缩/压缩内容?如果是这样,我现在做错了什么?
这是资源在 Chrome 网络面板中的显示方式,表明压缩正在运行:
这些是相关的requestheaders,显示请求是 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
这些是相关的response标题,表明Content-Length
and 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 处理。
Per 亚当的建议 https://stackoverflow.com/a/15172401/350278,我尝试将服务器端切换为 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。
Per 伯特兰的请求 https://stackoverflow.com/questions/15097712/how-can-i-use-deflated-gzipped-content-with-an-xhr-onprogress-function?noredirect=1#comment21565866_15097712,这是请求:
$.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);
});