http%3a%2f%2f百度下载:

HTTP 协议中 Vary 的一些研究 | JerryQu 的小站
HTTP 协议中 Vary 的一些研究文章目录
经常抓包看 HTTP 请求的同学应该对 Vary 这个响应头字段并不陌生,它有什么用?用
工具检查页面时,经常看到「Specify a Vary: Accept-Encoding header(请指定一个 Vary: Accept-Encoding 标头)」这样的建议,为什么要这样做?本文记录我对 Vary 的一些研究,其中就包含这些问题的答案。
HTTP 内容协商
要了解 Vary 的作用,先得了解 HTTP 的内容协商机制。有时候,同一个 URL 可以提供多份不同的文档,这就要求服务端和客户端之间有一个选择最合适版本的机制,这就是内容协商。
协商方式有两种,一种是服务端把文档可用版本列表发给客户端让用户选,这可以使用 300 Multiple Choices 状态码来实现。这种方案有不少问题,首先多一次网络往返;其次服务端同一文档的某些版本可能是为拥有某些技术特征的客户端准备的,而普通用户不一定了解这些细节。举个例子,服务端通常可以将静态资源输出为压缩和未压缩两个版本,压缩版显然是为支持压缩的客户端而准备的,但如果让普通用户选,很可能选择错误的版本。
所以 HTTP 的内容协商通常使用另外一种方案:服务端根据客户端发送的请求头中某些字段自动发送最合适的版本。可以用于这个机制的请求头字段又分两种:内容协商专用字段(Accept 字段)、其他字段。
首先来看 Accept 字段,详见下表:
请求头字段
响应头字段
告知服务器发送何种媒体类型
Content-Type
Accept-Language
告知服务器发送何种语言
Content-Language
Accept-Charset
告知服务器发送何种字符集
Content-Type
Accept-Encoding
告知服务器采用何种压缩方式
Content-Encoding
例如客户端发送以下请求头:
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:zh-CN,en-US;q=0.8,q=0.6
表示它可以接受任何 MIME 类型的资源;支持采用 gzip、deflate 或 sdch 压缩过的资源;可以接受 zh-CN、en-US 和 en 三种语言,并且 zh-CN 的权重最高(q 取值 0 - 1,最高为 1,最低为 0,默认为 1),服务端应该优先返回语言等于 zh-CN 的版本。
浏览器的响应头可能是这样的:
Content-Type: text/javascript
Content-Encoding: gzip
表示这个文档确切的 MIME 类型是 text/javascript;文档内容进行了 gzip 压缩;响应头没有 Content-Language 字段,通常说明返回版本的语言正好是请求头 Accept-Language 中权重最高的那个。
有时候,上面四个 Accept 字段并不够用,例如要针对特定浏览器如 IE6 输出不一样的内容,就需要用到请求头中的 User-Agent 字段。类似的,请求头中的 Cookie 也可能被服务端用做输出差异化内容的依据。
由于客户端和服务端之间可能存在一个或多个中间实体(如缓存服务器),而缓存服务最基本的要求是给用户返回正确的文档。如果服务端根据不同 User-Agent 返回不同内容,而缓存服务器把 IE6 用户的响应缓存下来,并返回给使用其他浏览器的用户,肯定会出问题 。
所以 HTTP 协议规定,如果服务端提供的内容取决于 User-Agent 这样「常规 Accept 协商字段之外」的请求头字段,那么响应头中必须包含 Vary 字段,且 Vary 的内容必须包含 User-Agent。同理,如果服务端同时使用请求头中 User-Agent 和 Cookie 这两个字段来生成内容,那么响应中的 Vary 字段看上去应该是这样的:
Vary: User-Agent, Cookie
也就是说 Vary 字段用于列出一个响应字段列表,告诉缓存服务器遇到同一个 URL 对应着不同版本文档的情况时,如何缓存和筛选合适的版本。
有 BUG 的缓存服务
再来看 PageSpeed 的「Specify a Vary: Accept-Encoding header」这个提示,按照上面的说明,Accept-Encoding 属于内容协商专用字段,服务端只需要在响应头中增加 Content-Encoding 字段,用来指明内容压缩格式;或者不输出 Content-Encoding 表明内容未经过压缩就可以了。而缓存服务器,应该针对不同的 Content-Encoding 缓存不同内容,再根据具体请求中的 Accept-Encoding 字段返回最合适的版本。
但是有些实现得有 BUG 的缓存服务器,会忽略响应头中的 Content-Encoding,从而可能给不支持压缩的客户端返回缓存的压缩版本。有两个方案可以避免这种情况发生:
将响应头中的 Cache-Control 字段设为 private,告诉中间实体不要缓存它;
增加 Vary: Accept-Encoding 响应头,明确告知缓存服务器按照 Accept-Encoding 字段的内容,分别缓存不同的版本;
通常为了更好的利用中间实体的缓存功能,我们都用第二种方案。
对于 css、js 这样的静态资源,只要客户端支持 gzip,服务端应该总是启用它;同时为了避免有 BUG 的缓存服务器给用户返回错误的版本,还应该输出 Vary: Accept-Encoding。
Nginx 和 SPDY
通常,上面说的这些工作,Web Server 都可以帮我们搞定。对于 Nginx 来说,下面这个配置可以自动给启用了 gzip 的响应加上 Vary: Accept-Encoding:
用 curl 验证我博客的 js 文件,响应头如下:
jerry@www:~$ curl --head /.../xx.js
HTTP/1.1 200 OK
Server: nginx
Date: Tue, 31 Dec 2013 16:34:48 GMT
Content-Type: application/x-javascript
Content-Length: 66748
Last-Modified: Tue, 31 Dec 2013 14:30:52 GMT
Connection: keep-alive
Vary: Accept-Encoding
ETag: "52c2d51c-104bc"
Expires: Fri, 29 Dec 2023 16:34:48 GMT
Cache-Control: max-age=
Strict-Transport-Security: max-age=
Accept-Ranges: bytes
可以看到,服务端正确输出了「Vary: Accept-Encoding」,一切正常。
但是用 Chrome 自带抓包工具看下,这个响应头却是这样:
HTTP/1.1 200 OK
cache-control: max-age=
content-encoding: gzip
content-type: application/x-javascript
date: Tue, 31 Dec 2013 16:35:27 GMT
expires: Fri, 29 Dec 2023 16:35:27 GMT
last-modified: Tue, 31 Dec 2013 14:30:52 GMT
server: nginx
status: 200
strict-transport-security: max-age=
version: HTTP/1.1
我的博客支持 SPDY/2 协议,用 Chrome 访问我博客会走 SPDY,所以上面的响应头看上有点不同寻常,例如字段名都变成了小写;多了 status、version 等字段,这些变化下次专门介绍(注:见「」)。神奇的是尽管服务端没任何变化,但响应中的 Vary: Accept-Encoding 却不见了。
SPDY 规定客户端必须支持压缩,这意味着 SPDY 服务器可以直接启用压缩而不用关心请求头中的 Accept-Encoding 字段。下面这段来自 Nginx 支持的 SPDY/2 协议:
User-agents are expected to support gzip and deflate compression. Regardless of the Accept-Encoding sent by the user-agent, the server may select gzip or deflate encoding at any time.
于是,对于支持 SPDY 的客户端来说,Vary: Accept-Encoding 没有用途,Nginx 选择直接去掉它,可以节省一点流量。curl 或其他不支持 SPDY 协议的客户端还是走 HTTP 协议,所以看到的响应头是常规的。
Nginx 的这个做法是否合适一直有争论,实际上并不是所有支持 SPDY 的 Web Server 都会这么做。例如即使通过 SPDY 协议访问 Google 首页的 js 文件,依然可以看到 vary: Accept-Encoding:
HTTP/1.1 200 OK
status: 200 OK
version: HTTP/1.1
age: 25762
alternate-protocol: 443:quic
cache-control: public, max-age=
content-encoding: gzip
content-length: 154614
content-type: text/ charset=UTF-8
date: Tue, 31 Dec 2013 23:23:51 GMT
expires: Wed, 31 Dec 2014 23:23:51 GMT
last-modified: Mon, 16 Dec 2013 21:54:35 GMT
server: sffe
vary: Accept-Encoding
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
另外,现阶段 Chrome 和 Firefox 都支持 SPDY 协议,但 PageSpeed Chrome 版和 Firefox 版都没有针对 SPDY 协议做特别处理,所以用它们测试我的博客,还是会提示「Specify a Vary: Accept-Encoding header」,这有点让人哭笑不得。不过
已经更新规则,估计扩展版也快了。
PS:Vary 在 IE 下有很多坑,使用时要格外小心。网上这部分文章比较多,例如 hax 早年写的 ,可以点过去了解下。
本文链接:--EOF--提醒:本文最后更新于 515 天前,文中所描述的信息可能已发生改变,请谨慎使用。专题「HTTP 相关」的其他文章笔记本电脑
分体台式机
全能赢变以简致胜
一体台式机
全能赢变以简致胜
智能家庭生活中心
时尚设计潮流体验
私享影院一键直达
优质生活实惠之选
引领智能轻松享受
笔记本电脑
分体台式电脑
全能赢变以简致胜
一体台式电脑
大客户之卓越智选
大客户之高效慧选
全能赢变以简致胜
商务经典智能便携
商务平板创新工具
打印机及耗材
巅峰之作专业首选
玲珑身形极致强大
中坚力量出众表现
超值首选典范之作
平台解决方案
行业解决方案
Lenovo服务
智能电视服务
企业级服务
400-822-2008订购热线: |  |  | 
中国人类遗传资源管...
科技部社会发展科技司
有关专业司
科技部发展计划司委...
有关专业司
科技部发展计划司委...
有关专业司
科技部基础研究司
科技部基础研究司
科技部高新技术发展...
科技部高新技术发展...
科技部农村科技司
科技部社会发展科技司
科技部农村科技司
科技部火炬高技术产...
科技部火炬高技术产...
创新基金管理中心负...
科学技术部政府信息公开申请表
2013年度国家科技奖励推荐工作手册
国家科学技术奖励项目异议登记表
设计人类遗传资源的国际
中国人类遗传资源
设计人类遗传资源的国际
中国人类遗传资源
设计人类遗传资源的国际
中国人类遗传资源
设计人类遗传资源的国际
中国人类遗传资源
设计人类遗传资源的国际
中国人类遗传资源
设计人类遗传资源的国际
中国人类遗传资源
设计人类遗传资源的国际
中国人类遗传资源
设计人类遗传资源的国际
中国人类遗传资源
设计人类遗传资源的国际
中国人类遗传资源
设计人类遗传资源的国际
中国人类遗传资源
设计人类遗传资源的国际
中国人类遗传资源
设计人类遗传资源的国际
中国人类遗传资源
设计人类遗传资源的国际
中国人类遗传资源
设计人类遗传资源的国际
中国人类遗传资源
设计人类遗传资源的国际
中国人类遗传资源
设计人类遗传资源的国际
中国人类遗传资源
设计人类遗传资源的国际
中国人类遗传资源
设计人类遗传资源的国际
中国人类遗传资源
设计人类遗传资源的国际
中国人类遗传资源
设计人类遗传资源的国际
中国人类遗传资源}

我要回帖

更多关于 http%3a%2f%2f百度下载 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信