【问题标题】:What is the function of the "Vary: Accept" HTTP header?“Vary: Accept” HTTP 标头的作用是什么?
【发布时间】:2010-12-30 19:57:09
【问题描述】:

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

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

现在我不确定以下内容的含义: header('变化:接受'); 我不太确定 'Vary: Accept' 究竟会做什么......

我找到的唯一解释是:

在 Content-Type 标头之后,一个 Vary 标头发送到(如果我理解的话 正确)告诉中间缓存, 像代理服务器一样,内容 文件类型因文件而异 关于客户的能力 请求文件。 http://www.456bereastreet.com/archive/200408/content_negotiation/

任何人都可以给我这个标题的“真实”解释(具有该值)。我想我理解以下内容: 变化:接受编码 代理上的缓存可以基于所服务页面的编码,但我不明白: 变化:接受

【问题讨论】:

  • 坦率地说 - 不要打扰。撇开该站点上的实现缺陷不谈,您唯一能从使用 XML 内容类型服务中获益的时候是当您执行 text/html 中无法完成的事情时 - 如果您正在做的所有事情正在切换 Doctype 和 xmlns,那么您将不会做这些事情。坚持文本/html。就此而言,您不妨坚持使用 HTML 4.01。
  • 是的,我理解这一点,我认为像这样的“问题”在 Web 开发中经常出现。感谢规范/RFC中的“应该”!
  • 在考虑使用 VARY 之前,您可能应该阅读以下内容:blogs.msdn.com/ieinternals/archive/2009/06/17/…
  • This videoVary: 标头有很好的解释。

标签: http caching proxy


【解决方案1】:
  • 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 请求标头“接受”定义了客户端可以处理的内容类型。如果您在同一个 URL 有两个相同内容的副本,仅在 Content-Type 上有所不同,那么使用 Vary: Accept 可能是合适的。

12 年 9 月 11 日更新:

我包含了自最初发布此评论以来已出现在 cmets 中的几个链接。它们都是 Vary 的真实示例(和问题)的极好资源:接受;如果您正在阅读此答案,则还需要阅读这些链接。

第一个来自杰出的 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 开发人员采取了不同的方法——尽管这似乎不是一个深思熟虑的选择。

【讨论】:

【解决方案2】:

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

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

对于 HTTP 缓存,这意味着必须格外小心地缓存响应。它只会对以后的请求有效匹配具有完全相同的Accept 标头

现在这仅在页面首先可缓存时才重要。默认情况下,PHP 页面不是。 PHP 页面可以通过发送某些标头(例如Expires)将输出标记为可缓存。但是否以及如何做到这一点是另一个问题。

【讨论】:

  • 是“可能得到”还是“应该得到”?
  • @Pacerier“可能会得到”是正确的。 Vary: Accept 并不意味着每个可能的不同 Accept 标头值都会产生不同且唯一的响应。这只意味着不同的Accept 标头可能产生不同的响应。
【解决方案3】:

这个google webmaster video 对HTTP Vary header 有很好的解释。

【讨论】:

    【解决方案4】:

    实际上有大量新功能即将推出(并且已经在 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
    

    【讨论】:

      猜你喜欢
      • 2012-06-18
      • 2011-11-27
      • 2012-01-23
      • 2013-05-14
      • 2017-07-20
      • 2011-04-08
      • 2011-12-21
      • 1970-01-01
      • 2023-03-23
      相关资源
      最近更新 更多