Cache-Control: max-age=0和no-ache有什么区别?

标题Cache-Control: max-age=0意味着内容被认为是陈旧的(并且必须立即重新获取),这实际上与Cache-Control: no-cache相同。

501032 次浏览
max-age
When an intermediate cache is forced, by means of a max-age=0 directive, to revalidate
its own cache entry, and the client has supplied its own validator in the request, the
supplied validator might differ from the validator currently stored with the cache entry.
In this case, the cache MAY use either validator in making its own request without
affecting semantic transparency.


However, the choice of validator might affect performance. The best approach is for the
intermediate cache to use its own validator when making its request. If the server replies
with 304 (Not Modified), then the cache can return its now validated copy to the client
with a 200 (OK) response. If the server replies with a new entity and cache validator,
however, the intermediate cache can compare the returned validator with the one provided in
the client's request, using the strong comparison function. If the client's validator is
equal to the origin server's, then the intermediate cache simply returns 304 (Not
Modified). Otherwise, it returns the new entity with a 200 (OK) response.

If a request includes the no-cache directive, it SHOULD NOT include min-fresh,
max-stale, or max-age. 

图片来源:http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4

不要接受这个答案-我必须阅读它才能理解它的真实用法:)

我算不上缓存专家,但马克·诺丁汉是。这是他的缓存文档。他在参考资料部分也有很好的链接。

根据我对这些文档的阅读,看起来max-age=0可以允许缓存对在“同一时间”进入的请求发送缓存响应,其中“同一时间”意味着它们看起来足够接近缓存,但no-cache不会。

我有同样的问题,并在我的搜索中找到了一些信息(你的问题是作为结果之一出现的)。

Cache-Control标头有两个方面。一面是Web服务器(又名“源服务器”)可以发送它的地方。另一面是浏览器可以发送它的地方(又名“用户代理”)。


当由源服务器发送时

我相信max-age=0只是告诉缓存(和用户代理)响应从一开始就过时了,所以他们应该在使用缓存副本之前重新验证响应(例如使用If-Not-Modified标头),而no-cache告诉他们他们必须在使用缓存副本之前重新验证。来自14.9.1什么是缓存

无缓存

…缓存不能使用响应 以满足后续请求 没有成功重新验证 源服务器。这允许 源服务器甚至防止缓存 通过已配置为 向客户端返回陈旧的响应 请求。

换句话说,缓存有时可能会选择使用陈旧的响应(尽管我相信他们必须然后添加一个Warning标头),但是no-cache表示无论如何都不允许他们使用陈旧的响应。也许当你在页面中生成棒球统计数据时,你会想要应该-重新验证行为,但是当你生成了对电子商务购买的响应时,你会想要必须-reval的行为。

虽然你在评论中说no-cache不应该阻止存储是正确的,但使用no-cache时实际上可能是另一个不同。我遇到了一个页面,缓存控制指令揭秘,上面写着(我不能保证它的正确性):

在实践中,IE和Firefox有 开始处理无缓存 指令,好像它指示 浏览器甚至不缓存页面。 我们开始观察这种行为 大约一年前。我们怀疑 此更改是由 广泛(和不正确)使用此 防止缓存的指令。

注意最近,“cache-control: 无缓存”也开始表现 比如“无存储”指令。

顺便说一句,在我看来Cache-Control: max-age=0, must-revalidate应该基本上与Cache-Control: no-cache的意思相同。所以也许这是一种获得no-cache必须重新验证行为的方法,同时避免no-cache明显迁移到与no-store做同样的事情(即。没有任何缓存)?


当由用户代理发送时

我相信shahkalpesh的回答适用于用户代理端。你也可以看看13.2.6消除多重响应

如果用户代理发送带有Cache-Control: max-age=0(又名“端到端重新验证”)的请求,那么沿途的每个缓存都将重新验证其缓存条目(例如使用If-Not-Modified标头),一直到源服务器。如果回复是304(未修改),则可以使用缓存实体。

另一方面,使用Cache-Control: no-cache(即“端到端重新加载”)发送请求不会重新验证,服务器一定不能在响应时使用缓存的副本。

在我最近对IE8和Firefox 3.5的测试中,似乎两者都符合RFC。然而,它们对源服务器的“友好性”不同。IE8将no-cache响应与max-age=0,must-revalidate相同的语义学。然而,Firefox 3.5似乎将no-cache视为等同于no-store,这在性能和带宽使用方面很糟糕。

默认情况下,鱿鱼缓存似乎永远不会存储任何带有no-cache标头的东西,就像Firefox一样。

我的建议是为您希望在每个请求上检查新鲜度的非敏感资源设置public,max-age=0,但仍然允许缓存的性能和带宽优势。对于具有相同考虑的每个用户项目,请使用private,max-age=0

我会完全避免使用no-cache,因为它似乎已经被一些浏览器和流行的缓存所破坏,功能相当于no-store

此外,不要模仿Akamai和Limelight。虽然他们本质上是将运行大量缓存阵列作为他们的主要业务,并且应该是专家,但他们实际上在导致从他们的网络下载更多数据方面拥有既得利益。谷歌可能也不是一个很好的仿真选择。他们似乎根据资源随机使用max-age=0no-cache

现在是老问题了,但是如果有人像我一样通过搜索遇到这个问题,IE9似乎将利用它来配置使用后退和前进按钮时资源的行为。当使用max-age=0时,浏览器将在后退/前进新闻上查看资源时使用最后一个版本。如果使用无缓存,资源将被重新获取。

关于IE9缓存的更多细节可以在这个msdn缓存博客文章上看到。

max-age=0

这相当于点击刷新,这意味着,给我最新的副本,除非我已经有了最新的副本。

无缓存

这是在单击刷新时按住Shift,这意味着,无论如何都要重做所有内容。

顺便说一句,值得注意的是,一些移动设备,特别是像iPhone这样的苹果产品 /iPad完全忽略像无缓存、无存储、Expires: 0或其他任何你可能试图强迫它们不重复使用过期表单页面的标题。

这给我们带来了无休止的头痛,因为我们试图解决用户iPad的问题,比如,在他们通过表单过程到达的页面上睡着了,比如3的第2步,然后设备完全忽略存储/缓存指令,据我所知,简单地从页面的最后状态获取页面的虚拟快照,也就是说,忽略它被明确告知的内容,而且,不仅如此,获取一个不应该存储的页面,并在没有真正检查它的情况下存储它,这导致了各种奇怪的会话问题,等等。

我只是添加这个,以防有人出现,无法弄清楚为什么他们会在iPhone和iPad上出现会话错误,这似乎是迄今为止该领域最严重的罪犯。

我已经对这个问题进行了相当广泛的调试器测试,这是我的结论,设备完全忽略了这些指令。

即使在常规使用中,我发现一些手机也完全无法通过例如Expires: 0检查新版本,然后检查最后修改的日期以确定是否应该获得新版本。

它根本不会发生,所以我被迫做的是将查询字符串添加到我需要强制更新的css/js文件中,这会欺骗愚蠢的移动设备认为这是一个它没有的文件,比如:my.css?v=1,然后v=2用于css/js更新。这在很大程度上有效。

顺便说一句,用户浏览器也,如果保留默认值,截至2016年,正如我不断发现的那样(我们对我们的网站做了很多更改和更新)也无法检查此类文件的最后修改日期,但查询字符串方法修复了这个问题。这是我注意到的客户端和办公室的人倾向于使用基本的正常用户默认值在他们的浏览器上,并没有意识到缓存问题与css/js等,几乎总是无法获得新的css/js的变化,这意味着默认值为他们的浏览器,主要是MSIE/Firefox,不做他们被告知要做什么,他们忽略更改和忽略最后修改的日期,不验证,即使Expires: 0显式设置。

这是一个很好的线程,有很多很好的技术信息,但同样重要的是要注意对这些东西的支持有多糟糕,特别是在移动设备中。每隔几个月,我必须添加更多层的保护,以防止他们无法遵循他们收到的头命令,或者正确地插入这些命令。

有一件事(令人惊讶)没有被提及是请求可以使用max-stale指令显式指示它将接受陈旧的数据。在这种情况下,如果服务器响应max-age=0,缓存只会认为响应陈旧,并可以自由使用它来满足客户端的请求[要求潜在陈旧的数据]。相比之下,如果服务器发送no-cache确实胜过客户端对陈旧数据的任何请求(使用max-stale),缓存必须重新验证。

这在关于缓存控制的MDN文档中直接回答:

大多数HTTP/1.0缓存不支持no-cache指令,因此 历史上max-age=0被用作解决方法。但只有 max-age=0可能导致缓存时重用陈旧的反应 与源服务器断开连接。must-revalidate解决了这个问题。 这就是为什么下面的示例等价于no-cache

Cache-Control: max-age=0, must-revalidate

但是现在,您可以简单地使用no-cache代替。

关于缓存验证的MDN文档中:

常说max-age=0must-revalidateno-cache具有相同的含义。

Cache-Control: max-age=0, must-revalidate

max-age=0表示 响应立即过时,must-revalidate意味着它必须 一旦它过时,就不会在没有重新验证的情况下重复使用-所以在 组合,语义学似乎与no-cache相同。

但是,max-age=0的用法是许多人使用的事实的残余 HTTP/1.1之前的实现无法处理no-cache 指令-因此为了解决这个限制,max-age=0被用作 解决方法

但是现在HTTP/1.1兼容的服务器被广泛部署,有 没有理由永远使用max-age=0-and-must-revalidate组合- 您应该只使用no-cache