HTTP 内容协商
请求头字段 | 说明 | 响应头字段 |
Accept | 告知服务器发送何种媒体类型 | Content-Type |
Accept-Language | 告知服务器发送何种语言 | Content-Language |
Accept-Charset | 告知服务器发送何种字符集 | Content-Type |
Accept-Encoding | 告知服务器采用何种压缩方式 | Content-Encoding |
Accept-CH | 列出了服务器可以用来选择合适响应的配置数据 |
如果服务端提供的内容取决于 User-Agent 这样「常规 Accept 协商字段之外」的请求头字段,那么响应头中必须包含 Vary 字段,且 Vary 的内容必须包含 User-Agent。同理,如果服务端同时使用请求头中 User-Agent 和 Cookie 这两个字段来生成内容,那么响应中的 Vary 字段看上去应该是这样的:Vary: User-Agent, Cookie
也就是说 Vary 字段用于列出一个响应字段列表,告诉缓存服务器遇到同一个 URL 对应着不同版本文档的情况时,如何缓存和筛选合适的版本。
但是有些实现得有 BUG 的缓存服务器,会忽略响应头中的 Content-Encoding,使用 Vary: Accept-Encoding 响应头,明确告知缓存服务器按照 Accept-Encoding 字段的内容,分别缓存不同的版本;
即便服务端驱动型内容协商机制是最常用的对资源特定展现形式进行协商的方式,它存在如下几个缺点:
- 服务器对浏览器并非全知全能。即便是有了客户端示意扩展,也依然无法获取关于浏览器能力的全部信息。与客户端进行选择的代理驱动型内容协商机制不同,服务器端的选择总是显得有点武断。
- 客户端提供的信息相当冗长(HTTP/2 协议的首部压缩机制缓解了这个问题),并且存在隐私风险(HTTP 指纹识别技术)。
- 因为给定的资源需要返回不同的展现形式,共享缓存的效率会降低,而服务器端的实现会越来越复杂。