ChatGPT解决这个技术问题 Extra ChatGPT

no-cache 和 must-revalidate 之间的区别

来自 RFC 2616

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

no-cache 如果 no-cache 指令未指定字段名称,则缓存不得使用响应来满足后续请求,而无需与源服务器成功重新验证。这允许源服务器阻止缓存,即使缓存已配置为向客户端请求返回陈旧响应。

因此,它指示代理重新验证所有响应。

与此相比

must-revalidate 当缓存接收到的响应中存在 must-revalidate 指令时,该缓存不得在该条目变得陈旧后使用该条目来响应后续请求,而无需先向源服务器重新验证它

因此,它指示代理重新验证过时的响应。

特别是关于 no-cache,用户代理实际上是如何根据经验处理该指令的?

如果有 must-revalidatemax-age,那么 no-cache 有什么意义?

看到这个评论:

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

no-cache 虽然这个指令听起来像是在指示浏览器不要缓存页面,但还是有细微的差别。根据 RFC,“no-cache”指令告诉浏览器它应该在从缓存中提供页面之前与服务器重新验证。重新验证是一种巧妙的技术,可以让应用程序节省带宽。如果浏览器缓存的页面没有改变,服务器只是向浏览器发出信号,页面就会从缓存中显示出来。因此,浏览器(至少在理论上)将页面存储在其缓存中,但只有在服务器重新验证后才会显示它。实际上,IE 和 Firefox 已经开始将 no-cache 指令视为指示浏览器甚至不缓存页面。我们大约在一年前开始观察这种行为。我们怀疑此更改是由广泛(且不正确)使用此指令来防止缓存引起的。

有没有人对此有更官方的消息?

更新

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

这是我直到现在才把它放在心上的事情。 RFC 说不要轻易使用 must-revalidate。问题是,对于 Web 服务,您必须对未知的客户端应用程序采取负面看法并假设最坏的情况。任何陈旧的资源都有可能导致问题。

我刚刚考虑过的其他事情,没有 Last-Modified 或 ETags,浏览器只能再次获取整个资源。但是,使用 ETags,我观察到 Chrome 至少似乎对每个请求都重新验证。这使得这两个指令都没有实际意义,或者至少命名不佳,因为它们无法正确重新验证,除非请求还包含其他导致“始终重新验证”的标头。

我只是想让最后一点更清楚。通过仅设置 must-revalidate 但不包括 ETag 或 Last-Modified,代理只能再次获取内容,因为它没有任何内容可发送到服务器进行比较。

但是,我的经验测试表明,当响应中包含 ETag 或修改后的标头数据时,无论是否存在 must-revalidate 标头,代理总是会重新验证。

因此,must-revalidate 的重点是在它过时时强制“绕过缓存”,这只有在您设置了生命周期/年龄时才会发生,因此如果在没有年龄或其他标头的响应上设置了 must-revalidate,它实际上等效于 no-cache,因为响应将立即被视为陈旧。

——所以我要最终标记吉利的答案!

因此,从理论上讲,区别在于 validate-always 与 validate-if-stale,而实际上 no-cache 会被某些浏览器视为您引用的评论说 never-validate ...所以您应该选择使用哪一个基于您在实践中实际想要实现的缓存行为......
请阅读greenbytes.de/tech/webdav/…,看看这是否为您澄清了一些事情。
检查此决策树以获取答案 stackoverflow.com/a/49925190/3748498

A
Anish B.

我相信 must-revalidate 意味着:

一旦缓存过期,即使用户说陈旧的响应是可以接受的,也拒绝向用户返回陈旧的响应。

no-cache 意味着:

must-revalidate 加上响应立即变得陈旧的事实。

如果响应可缓存 10 秒,则 must-revalidate 在 10 秒后启动,而 no-cache 意味着 must-revalidate 在 0 秒后。

至少,这是我的解释。


这就是我现在看到的。有趣的部分是我的最后一段,没有 ETag 或 Last-Modified,代理没有任何东西可以用来验证它在缓存中的内容,并且必须再次下载整个有效负载。因此,当 RFC 说“重新验证”时,这可能意味着重新获取。
这也意味着 max-age=0, must-revalidateno-cache 是相同的
@Anshul,起初我认为'max-age = 0,must-revalidate和no-cache是相同的'是对的,但请参阅Jeffrey Fox的回答,这似乎表明这不太正确。
@Anshul 不,must-revalidateno-cache 对于新鲜响应具有不同的含义:如果缓存的响应是新鲜的(即响应尚未过期),must-revalidate 将使代理立即为其提供服务,而无需重新验证服务器,而使用 no-cache 时,代理必须重新验证缓存的响应,而不考虑新鲜度。资料来源:“HTTP - 权威指南”,第 182-183 页。
@MatthiasBraun 啊,我可以看到混乱的根源。可能我应该写 no-cachemax-age=0, must-revalidate 是相同的
J
Jeffrey Fox

max-age=0, must-revalidateno-cache 并不完全相同。使用 must-revalidate,如果服务器不响应重新验证请求,则浏览器/代理应该返回 504 错误。使用 no-cache,它只会显示缓存的内容,这可能是用户的首选(有一些陈旧的东西总比什么都没有好)。这就是为什么 must-revalidate 仅用于关键事务。


不确定您的 no-cache 解释。在 RFC 7234 中,“no-cache”响应指令指示响应不能用于满足后续请求,而无需在源服务器上成功验证。这允许原始服务器阻止缓存使用它来满足请求而不联系它,即使是通过已配置为发送陈旧响应的缓存。 这听起来类似于 must-revalidate 的限制
Jeffrey 是否有证据表明实现的行为与他所描述的一样?
我认为这个答案对于代理/磅服务器是正确的。但实际上,在这种情况下,浏览器不会返回 504。
所以 must-validate 表示 must-refresh
developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control 直接表示“no-cachemax-age=0, must-revalidate 表示相同的含义”。
r
rogerdpack

根据 Jeffrey Fox 对 no-cache 的解释,我在 chrome 52.0.2743.116 m 下进行了测试,结果表明 no-cachemust-revalidate 具有相同的行为,它们都将 NOT 使用本地缓存当服务器无法访问时,当服务器无法访问时,它们都会在点击浏览器的后退/前进按钮时使用缓存。如上所述,我认为 max-age=0, must-revalidateno-cache 相同,至少在实现上是这样。


当服务器可用于重新验证时,Chrome 会使用本地缓存吗? (即“If-Modified-Since”)。在这两种情况下?
D
D.jennis

同意@Jeffrey Fox 的部分回答:

max-age=0,must-revalidate 和 no-cache 并不完全相同。

不同意这部分:

使用 no-cache,它只会显示缓存的内容,这可能是用户更喜欢的(有一些陈旧的东西总比什么都没有好)。

RFC 文档中没有指定当 cache-control: no-cache 重新验证失败时实现应该做什么。这完全取决于实施。他们可能会抛出像 cache-control: must-revalidate 这样的 504 错误,或者只是从缓存中提供一个过时的副本。


J
Jason C

对于它的价值,the MDN page on HTTP validation 直接解决了这个问题(强调我的):

人们常说 max-age=0 和 must-revalidate 的组合与 no-cache 的含义相同。 Cache-Control: max-age=0, must-revalidate max-age=0 表示响应立即过时,must-revalidate 表示一旦过时,不得在没有重新验证的情况下重用它——所以结合起来,语义似乎与无缓存相同。然而,max-age=0 的使用是 HTTP/1.1 之前的许多实现无法处理 no-cache 指令这一事实的残余——因此为了解决这个限制,max-age=0 被用作一种解决方法。但是现在符合 HTTP/1.1 的服务器已经广泛部署,没有理由使用 max-age=0-and-must-revalidate 组合——您应该只使用 no-cache。

供参考(对于我们自己的个人缓存控制,呵呵)那个MDN页面最后一次更新是2022年6月1日;我在 2022 年 6 月 10 日取消了该报价 (archive June 8)。


R
Rich

我认为 max-age=0, must-revalidateno-cache 之间存在区别:

must-revalidate 情况下,如果返回 304 Not Modified,则允许客户端发送 If-Modified-Since 请求并从缓存中提供响应。

no-cache 情况下,客户端不得缓存响应,因此不应使用 If-Modified-Since


但是no-cache不代表no-store——有了no-cache,资源仍然可以缓存在客户端;它只是必须在使用前重新验证?
您将 no-cacheno-store 混为一谈。 no-cache 表示资源必须重新验证Revalidate 包括使用条件请求的选项,例如 If-None-MatchIf-Modified-Since
@JulesRandolph:你可能是对的。你有任何测试/演示吗?关于这个 q 的所有相互矛盾的无证据断言都令人沮丧。即使是接受的答案也只是说“至少,这是我的解释”。如果我有时间,我可能会设置一个测试平台并将其发布在这里。