什么是“Vary:Accept”HTTP头的function?

我使用PHP来生成dynamic网页。 正如下面的教程(见下面的链接)所述,当$ _SERVER ['HTTP_ACCEPT']允许时,XHTML文档的MIMEtypes应该是“application / xhtml + xml”。 由于您可以使用2种不同的MIME(“application / xhtml + xml”和“text / html”)提供相同的页面,因此您应该将“Vary”HTTP标头设置为“Accept”。 这将有助于caching代理。

链接: http : //keystonewebsites.com/articles/mime_type.php

现在我不确定:header('Vary:Accept'); 我不确定什么是“不同的:接受”的确会做…

我发现的唯一解释是:

在Content-Type头部之后,发送一个Vary头部(如果我理解正确的话)告诉中间高速caching,例如代理服务器,文档的内容types根据请求文档的客户端的能力而变化。 http://www.456bereastreet.com/archive/200408/content_negotiation/

任何人都可以给我一个关于这个头文件的“真实的”解释( 用这个值 )。 我想我理解的东西,如:Vary:Accept-Encoding其中代理的caching可以基于所服务的页面的编码,但我不明白:Vary:Accept

  • cache-control头是HTTP服务器告诉caching代理响应“新鲜”的主要机制。 (即,如何/如果长时间将响应存储在caching中)

  • 在某些情况下, cache-control指令是不够的。 来自HTTP工作组的讨论在此处被存档,描述了仅随语言改变的页面。 对于不同的头文件,这不是正确的用例,但是上下文对于我们的讨论是有价值的。 (虽然我认为Vary头部可以解决这个问题,但还是有一个更好的办法。)从那个页面:

对于代理复制服务器将会执行的操作而言, Vary是严格意义上的。

  • RFC2616“报头字段定义”从服务器angular度描述了报头使用情况, RFC2616“caching代理”angular度的“caching协商响应” 。 它旨在指定一组确定请求唯一性的HTTP请求标头。

一个人为的例子:

你的HTTP服务器有一个大的登陆页面。 你有两个略有不同的页面,具有相同的URL,取决于用户是否曾经在那里。 您根据Cookie区分请求和用户的“访问次数”。 但是,由于您的服务器的login页面太大,如果可能,您希望中​​间代理caching响应。

URL,Last-Modified和Cache-Control头文件不足以将此信息提供给caching代理,但是如果添加了Vary: Cookie ,则caching引擎会将Cookie头添加到其caching决策中。

最后,对于小stream量的dynamic网站 – 我总是发现了简单的Cache-Control: no-cache, no-storePragma: no-cache足够了。

编辑 – 更准确地回答你的问题:HTTP请求头“Accept”定义了客户端可以处理的内容types。 如果在同一个URL中有两个相同内容的副本,只有Content-Type不同,则可以使用Vary: Accept

9月12日更新:

自从评论最初发布以来,我在评论中包含了一些链接。 他们都是真实世界的例子(和问题)的优良资源Vary:Accept; 如果你正在阅读这个答案,你也需要阅读这些链接。

首先,来自EricLaw的杰出人物,介绍Internet Explorer对Vary头部的行为以及向开发人员提出的一些挑战: Vary Header阻止IE中的caching 。 简而言之,IE(IE9之前)不会caching使用Vary头的任何内容,因为请求caching不包含HTTP请求头。 EricLaw(现实世界中的Eric Lawrence)是IE团队的项目经理。

第二个来自Eran Medan,并且正在讨论Chrome中与Vary相关的意外行为: Backing不能正确处理Vary头文件 。 这与IE的行为有关,除了Chrome开发者采取了不同的方法 – 尽pipe它似乎并不是一个有意的select。

Vary: Accept简单地说,响应是基于请求中的Accept头来生成的。 具有不同Accept头的请求可能会得到不同的响应。

(您可以看到,链接的PHP代码查看$HTTP_ACCEPT ,这是Accept请求头的值。)

对于HTTPcaching来说,这意味着必须特别小心caching响应。 只有在Accept完全相同的报头后才能成为有效的匹配。

现在这只在页面caching起来的时候才重要。 默认情况下,PHP页面不是。 PHP页面可以通过发送某些标题(例如Expires )将输出标记为可caching。 但是,是否和如何做到这一点是一个不同的问题。

实际上,即将推出的大量新function(并已在Chrome中)使Vary头部非常有用。 例如,考虑客户暗示 。 例如,在与图像结合使用时,客户端提示允许服务器根据以下条件优化图像等资源:

  • 图像宽度
  • 视口宽度
  • 浏览器支持的编码types(想想WebP)
  • 下行链路(基本上是networking速度)

所以支持这些function的服务器会设置Vary头来表明这一点。

Chrome会通过将“image / webp”设置为每个请求的Vary标头的一部分来宣传WebP支持。 因此,如果浏览器支持WebP,服务器可能会将其重写为WebP,因此代理需要检查头,以便不cachingWebP图像,然后将其提供给不支持WebP的浏览器。 显然,如果你的服务器没有这样做,那就没关系了。 因此,由于服务器的响应在Accept请求头部上有所不同,所以响应必须包括以免混淆代理:

 Vary: Accept 

另一个例子可能是图像的宽度。 在移动浏览器中,与从桌面浏览器查看的情况相比,对于响应式图像, Width标题可能相当小。 所以在这种情况下, Width将被添加到Vary头中,这对于代理不caching小移动版本并将其提供给桌面浏览器是必不可less的,反之亦然。 在这种情况下,标题可能包括:

 Vary: Accept, Width 

或者在一个服务器支持所有的客户端提示规范的情况下,头文件会是这样的:

 Vary: Accept, DPR, Width, Save-Data, Downlink 

这个谷歌网站pipe理员video有一个关于HTTP Vary头很好的解释。