对于可以更改的内容,哪些是与缓存相关的最佳HTTP标头?

时间:2012-07-31 10:22:15

标签: http caching cache-control http-caching no-cache

我们有几个文件通过HTTP提供,并且会不时更改。

哪些是与缓存相关的HTTP标头,我们应该在HTTP响应中返回以优化浏览器加载速度,同时强制浏览器验证它是否具有该文件的最新版本?

我们已经设置了一个过期日期的“过期”标题(此时似乎已达成共识)。

但有些人建议设置此标题:

Cache-Control: no-cache, no-store, must-revalidate

但是这个标题的问题在于它阻止浏览器保留文件的本地副本,因此每次使用200响应代码即使文件没有更改也会下载文件。

如果我只是使用:

Cache-Control: no-cache

然后浏览器(至少Firefox 14和Chrome 20)保留本地副本,发送If-Modified-SinceIf-None-Match标头,服务器返回304代码并且不下载文件内容。 这是可以随时更改的这些文件的最佳行为。

问题是我不知道设置“no-cache”是否足以强制所有浏览器(包括旧的但仍然使用的版本)和代理服务器重新验证其服务器的本地缓存副本。

最后,Pragma: no-cache标题怎么样?它也应该包含在HTTP响应中吗?

3 个答案:

答案 0 :(得分:5)

Google开发者文档有nice documentation on caching,并提供了一些不错的模式。

例如,它有一个用于定义最佳缓存控制策略的流程图。

enter image description here

此外,它定义了一个很好的模式,可以将指纹添加到文件中,并设置较长时间(如一年)的过期时间。

  
      
  • 在资源“过期”
  • 之前使用本地缓存的响应   
  • 在URL中嵌入文件内容指纹使我们能够强制客户端更新到新版本的响应
  •   
  • 每个应用程序都需要定义自己的缓存层次结构以获得最佳性能
  •   

enter image description here

  

定义每资源缓存策略的能力使我们能够   定义“缓存层次结构”,使我们不仅可以控制多长时间   每个都被缓存,但也看到新版本的速度   游客。例如,让我们分析上面的例子:

     
      
  • HTML标记为“no-cache”,这意味着浏览器将始终在每个请求上重新验证文档并获取   如果内容发生变化,最新版本。此外,在HTML标记内   我们在CSS和JavaScript资产的URL中嵌入了指纹:if   这些文件的内容会改变,而不是页面的HTML   也会改变HTML响应的新副本   下载。
  •   
  • 允许CSS由浏览器和中间缓存(例如CDN)缓存,并设置为在1年后过期。请注意,我们可以使用
      因为我们嵌入了文件
    ,所以安全的“远期未来到期”是1年   指纹文件名:如果CSS更新,则URL将更改   同样。
  •   
  • JavaScript也设置为在1年后过期,但被标记为私有,可能是因为它包含一些私人用户数据   CDN不应该缓存。
  •   
  • 图像在没有版本或唯一指纹的情况下进行缓存,并设置为在1天后过期。
  •   
     

ETag,Cache-Control和唯一URL的组合使我们能够   提供最好的世界:长期的到期时间,控制权   可以缓存响应的位置和按需更新

答案 1 :(得分:1)

最好的方法,可能不是100%满足您的需求:

Cache-Control:max-age=315360000, public
Expires:Tue, 23 Aug 2022 10:53:13 GMT

并为文件提供一个"内容相关的文件名"例如stylesheet_v32.css。 内容更改后,将文件名+引用更改为,浏览器将获取最新版本。如果文件名保留,浏览器不需要请求它。

这在浏览器中是安全且一致的。

依靠Cache-Control: no-cache和浏览器保存它无论如何都是我不想做的。

答案 2 :(得分:0)

我找到了两种强制客户端重新检查缓存的方法:

Cache-Control: max-age=0, must-revalidate
Expires: Thu, 01 Jan 1970 00:00:00 GMT

这至少适用于Firefox。我认为IE和Chrome也会做出正确的反应。它应该适用于使用HTTP / 1.0的旧浏览器。

使用HTTP 1.1,您可以使用ETag。在这种情况下,must-revalidate选项不是必需的,因为让ETag足以让客户做出反应,就好像must-revalidate那样:

Cache-Control: max-age=0
ETag: 123
Expires: Thu, 01 Jan 1970 00:00:00 GMT

这将告诉客户端使用ETag 123创建数据的缓存版本,并在每次需要该数据的副本时重新检查服务器。然后,您可以使用304 Not Modified回复。

您最终无法使用的两个选项是:no-cacheno-store

如果您想阻止中间缓存缓存数据,请务必将private添加到Cache-Control选项中。

作为一个有趣的功能,您还可以使用较小的最大年龄(例如几分钟)让客户端缓存数据一段时间,然后发送GET即可用304回答:

Cache-Control: max-age=300
ETag: 123
Expires: Tue, 29 Mar 2015 15:05:00 GMT

在这种情况下,浏览器预计不会检查新数据5分钟。之后,它会向您发送If-None-Match: 123