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

问题描述:

我使用PHP来生成动态网页。如以下教程所述(请参阅下面的链接),当$ _SERVER ['HTTP_ACCEPT']允许时,MIME类型的XHTML文档应该是“application/xhtml + xml”。由于您可以使用2种不同的MIME(“application/xhtml + xml”和“text/html”)提供相同的页面,因此您应该将“Vary”HTTP标头设置为“Accept”。这将有助于缓存代理。“Vary:Accept”HTTP头的功能是什么?

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

现在我不知道的寓意: 头( '有所不同:接受'); 我真的不知道什么“有所不同:接受”将精确地做......

我发现的唯一解释是:

的Content-Type头后,因人而异 头中发送到(如果我正确理解它 )告诉中间缓存 像代理服务器一样,文档的内容 根据请求文档的客户端 的功能而变化,具体取决于 。 http://www.456bereastreet.com/archive/200408/content_negotiation/

任何人都可以给我这个头的“真实”的解释(与价值)。我想我明白了诸如: 有所不同:接受编码 凡代理缓存可以基于网页的编码服务,但我不明白: 各不相同:接受

+1

坦率地说 - 不要打扰。撇开该网站实施中的缺陷,唯一一次从XML内容类型服务中获得好处的时候是,当你做一些无法在text/html中完成的事情 - 并且如果你在做所有事情正在转换Doctype和xmlns,那么你不会去做那些事情。坚持text/html。对于这个问题,你可能会坚持使用HTML 4.01。 – Quentin 2009-12-29 17:22:42

+0

是的,我明白这一点,我认为像这样的“问题”在Web开发中经常出现。感谢规范/ RFC中的“应该”! – AlexV 2009-12-29 18:22:33

+2

在考虑使用VARY之前,您应该阅读以下内容:http://blogs.msdn.com/ieinternals/archive/2009/06/17/Vary-Header-Prevents-Caching-in-IE.aspx。 – EricLaw 2010-01-05 03:44:55

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

  • 在某些情况下,cache-control指令是不够的。来自HTTP工作组的讨论被存档here,,其描述了仅随语言改变的页面。这是而不是正确使用情况的变化标题,但上下文对于我们的讨论是有价值的。 (虽然我相信Vary标头可以解决这个问题在这种情况下,有一个更好的办法。)在这个页面:

Vary是严格的情况下,这是绝望或过于复杂的代理来复制服务器将执行的操作。

一个人为的例子:

你的HTTP服务器有一个大的着陆页。您有两个略有不同的页面,并且具有相同的URL,具体取决于用户之前是否在那里。您根据Cookie区分请求和用户的“访问计数”。但是,由于您的服务器的着陆页太大,您希望中​​介代理缓存响应,如果可能的话。

URL,Last-Modified和Cache-Control标头不足以将此洞察信息提供给缓存代理,但如果添加Vary: Cookie,则缓存引擎会将Cookie标头添加到其缓存决策中。

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

编辑 - 更准确地回答你的问题:HTTP请求头'Accept'定义了客户端可以处理的内容类型。如果您在同一个网址上有两个相同内容的副本,只有内容类型不同,则使用Vary: Accept可能是适当的。

更新12年9月11日:

我包括已经出现了意见,因为此评论最初发布几个链接。它们都是用Vary实现的真实案例(和问题)的绝佳资源:Accept;如果你正在阅读这个答案,你也需要阅读这些链接。

第一个来自杰出的EricLaw,关于Internet Explorer的Vary头部行为以及它向开发人员提出的一些挑战:Vary Header Prevents Caching in IE。简而言之,IE(IE9之前)不会缓存使用Vary头的任何内容,因为请求缓存不包含HTTP请求头。 EricLaw(Eric Lawrence在现实世界中)是IE团队的项目经理。

第二个来自Eran Medan,并且正在讨论Chrome中与Vary相关的意外行为:Backing doesn't handle Vary header correctly。这与IE的行为有关,除了Chrome开发者采取了不同的方法 - 尽管它似乎并不是一个有意的选择。

+3

在Chrome浏览器按钮中注意这一点,对这个错误(现在是由于某种原因wontfix)有点火焰战争http://code.google.com/p/chromium/issues/detail? id = 94369 – 2012-09-07 02:39:44

+5

@EranMedan Chrome bug已经修复。 – 2014-05-05 21:43:23

Vary: Accept只是表示响应是基于请求中的Accept标头生成的。具有不同Accept标头的请求可能会得到不同的响应。

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

要HTTP缓存,这意味着响应必须格外小心被缓存。只有在后面的请求Accept标头完全相同时才有效。

现在,这只有在页面缓存在第一位时才有意义。默认情况下,PHP页面不是。 PHP页面可以通过发送某些标题(例如Expires)将输出标记为可缓存。但是是否以及如何去做是一个不同的问题。

+0

它是“可能得到”还是应该得到? – Pacerier 2011-09-25 22:00:07

+6

@Pacerier“可能会得到”是正确的。 'Vary:Accept'并不意味着每一个可能不同的'Accept'头部值都会产生不同且独特的响应。这只意味着不同的'Accept'头*可能会产生不同的响应。 – 2011-09-28 21:29:52

google webmaster video有关于HTTP Vary标题的很好的解释。

实际上有很多新功能即将推出(并且已经在Chrome中),使得Vary标头非常有用。例如,考虑Client Hinting。当与图像结合使用,例如,客户机提示允许服务器优化资源诸如取决于图像:

  • 图片宽度
  • 视口宽度
  • 编码的由浏览器支持的类型(认为WebP的)
  • 下行链路(网络基本上速度)

所以它支持的那些特征将设置Vary报头中的服务器,以指示。

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

Vary: Accept 

另一个例子是图像的宽度。在移动浏览器上,Width标题对于响应式图像而言可能相当小,与从桌面浏览器查看时相比较。因此,在这种情况下,Width将被添加到Vary标头对于代理不缓存小型移动版本并将其提供给桌面浏览器至关重要,反之亦然。在这种情况下,头部可能包括:

Vary: Accept, Width 

或在一台服务器支持的所有客户端提示规格的情况下,标题会是这样的:

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