来自RFC 2616

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1

no - cache 如果no-cache指令没有指定字段名,则缓存 一定不要使用响应来满足后续的请求没有 与原始服务器的重新验证成功。这允许一个原点 服务器来防止缓存,即使缓存已配置为 向客户端请求返回过时的响应。

所以它指导代理人重新验证所有的反应。

相比之下

must-revalidate 当必须重新验证指令出现在收到的响应中 通过缓存,该缓存绝对不能使用该条目后,它变得陈旧 对后续请求作出响应,而不首先对其进行重新验证 源服务器

所以它会引导代理重新验证过时的响应。

特别是关于无缓存,这是用户代理实际上,经验对待这个指令吗?

如果必须重新验证和max-age,那么无缓存还有什么意义呢?

请看下面的评论:

http://palpapers.plynt.com/issues/2008Jul/cache-control-attributes/

no-cache Though this directive sounds like it is instructing the browser not to cache the page, there’s a subtle difference. The “no-cache” directive, according to the RFC, tells the browser that it should revalidate with the server before serving the page from the cache. Revalidation is a neat technique that lets the application conserve band-width. If the page the browser has cached has not changed, the server just signals that to the browser and the page is displayed from the cache. Hence, the browser (in theory, at least), stores the page in its cache, but displays it only after revalidating with the server. In practice, IE and Firefox have started treating the no-cache directive as if it instructs the browser not to even cache the page. We started observing this behavior about a year ago. We suspect that this change was prompted by the widespread (and incorrect) use of this directive to prevent caching.

有人有更正式的消息吗?

更新

当且仅当对表示的请求验证失败可能导致不正确的操作时,服务器才应该使用must-revalidate指令,例如未静默执行的金融事务。

直到现在,我才把这件事放在心上。RFC说不要轻易使用“必须重新验证”。问题是,对于web服务,你必须采取消极的态度,并为你未知的客户端应用程序做最坏的打算。任何陈旧的资源都有可能导致问题。

我刚刚考虑的另一件事是,没有Last-Modified或ETags,浏览器只能再次获取整个资源。然而,对于ETags,我观察到Chrome至少似乎对每个请求都重新验证。这使得这两个指令都没有意义,或者至少命名很糟糕,因为它们不能正确地重新验证,除非请求还包括其他会导致“总是重新验证”的头文件。

我想把最后一点讲清楚。通过设置必须重新验证,但不包括ETag或Last-Modified,代理只能再次获得内容,因为它没有什么可以发送到服务器进行比较。

然而,我的经验测试表明,当响应中包含ETag或修改的报头数据时,无论是否存在必须重新验证的报头,代理总是重新验证。

因此,必须重新验证的重点是在它失效时强制“绕过缓存”,这只会发生在你设置了生命周期/年龄时,因此,如果必须重新验证设置在一个没有年龄或其他报头的响应上,它实际上相当于没有缓存,因为响应将被认为立即失效。

所以我终于要给Gili的答案打分了!


我认为必须重新验证意味着:

一旦缓存过期,拒绝向用户返回过时的响应 即使他们说陈腐的回答是可以接受的。

而无缓存意味着:

必须重新验证,加上响应立即变得陈旧的事实。

如果响应可缓存10秒,则必须在10秒后重新验证,而无缓存意味着必须在0秒后重新验证。

至少,这是我的解释。


Max-age =0,必须重新验证和无缓存并不完全相同。使用必须重新验证,如果服务器没有响应重新验证请求,浏览器/代理应该返回一个504错误。在没有缓存的情况下,它只会显示缓存的内容,这可能是用户更喜欢的(有一些陈旧的内容总比没有要好)。这就是为什么必须重新验证仅适用于关键事务的原因。


根据Jeffrey Fox关于无缓存的解释,我在chrome 52.0.2743.116 m下进行了测试,结果显示无缓存具有与必须重新验证相同的行为,当服务器不可达时,它们都不会使用本地缓存,并且,当服务器不可达时,它们都将在点击浏览器的后退/前进按钮时使用缓存。 如上所述,我认为max-age=0, must-revalidate与no-cache是相同的,至少在实现中是这样。


我认为max-age=0, must-revalidate和no-cache之间是有区别的:

在必须重新验证的情况下,允许客户端发送一个if -Modified- since请求,如果返回304 Not Modified,则从缓存中提供响应。

在无缓存的情况下,客户端不能缓存响应,因此不应该使用If-Modified-Since。


同意@Jeffrey Fox回答的部分内容:

Max-age =0,必须重新验证和无缓存并不完全相同。

不同意这部分:

在没有缓存的情况下,它只会显示缓存的内容,这可能是用户更喜欢的(有一些陈旧的内容总比没有要好)。

当cache-control: no-cache重新验证失败时,实现应该怎么做RFC文档中没有指定。这完全取决于实现。它们可能会抛出一个504错误,比如cache-control:必须重新验证或者只是从缓存中提供一个陈旧的副本。


对于它的价值,MDN页面的HTTP验证直接解决这个问题(强调我的):

It is often stated that the combination of max-age=0 and must-revalidate has the same meaning as no-cache. Cache-Control: max-age=0, must-revalidate max-age=0 means that the response is immediately stale, and must-revalidate means that it must not be reused without revalidation once it is stale — so in combination, the semantics seem to be the same as no-cache. However, that usage of max-age=0 is a remnant of the fact that many implementations prior to HTTP/1.1 were unable to handle the no-cache directive — and so to deal with that limitation, max-age=0 was used as a workaround. But now that HTTP/1.1-conformant servers are widely deployed, there's no reason to ever use that max-age=0-and-must-revalidate combination — you should instead just use no-cache.

作为参考(对于我们自己的个人缓存控制,嘿),MDN页面最后一次更新是在2022年6月1日;我在2022年6月10日引用了这句话(档案6月8日)。