来自RFC 2616
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1
无缓存
如果无缓存指令未指定字段名,则缓存在没有成功地与原始服务器重新验证。这允许一个原点服务器以阻止缓存,即使缓存已配置为返回对客户端请求的过时响应。
因此,它指示代理重新验证所有响应。
将其与进行比较
必须重新验证
当收到的响应中存在"必须重新验证"指令时对于缓存,该缓存在条目过期后不得使用该条目在不首先使用重新验证的情况下响应后续请求原始服务器
因此,它指示代理重新验证过时的响应。
特别是关于no-cache
,这是用户代理实际、经验地对待该指令的方式吗?
如果有must-revalidate
和max-age
,那么no-cache
有什么意义?
请参阅以下评论:
http://palpapers.plynt.com/issues/2008Jul/cache-control-attributes/
无缓存
尽管这个指令听起来像是在指示浏览器不要缓存页面,有一个细微的区别。"无缓存"指令,根据RFC,告诉浏览器应该使用服务器,然后再从缓存中提供页面。重新验证是整洁的技术,让应用程序节省带宽。如果浏览器缓存的页面没有改变,服务器只是发出信号并从高速缓存中显示页面。因此浏览器(至少在理论上)将页面存储在其缓存中,但是仅在与服务器重新验证后显示。在实践中,IE和Firefox已经开始将无缓存指令视为指示浏览器甚至不要缓存页面。我们开始观察大约一年前的这种行为。我们怀疑这一变化由于该指令的广泛(和不正确)使用阻止缓存。
有人对此有更正式的消息吗?
更新
如果且仅当未能验证对表示的请求可能导致不正确的操作(如静默未执行的金融交易)时,服务器才应使用must-revalidate指令。
直到现在我才把这件事放在心上。RFC表示,不要使用必须轻量重新验证。问题是,对于网络服务,你必须持负面看法,并为你未知的客户端应用程序设想最坏的情况。任何陈旧的资源都有可能导致问题。
我刚刚考虑过的另一件事是,如果没有Last Modified或ETag,浏览器只能再次获取整个资源。然而,对于ETag,我观察到Chrome似乎至少在每次请求时都会重新验证。这使得这两个指令都没有意义,或者至少命名不好,因为它们不能正确地重新验证,除非请求还包括其他导致"始终重新验证"的头。
我只想把最后一点说得更清楚。通过只设置must-revalidate
,但不包括ETag或Last Modified,代理只能再次获取内容,因为它没有什么要发送到服务器进行比较的内容。
然而,我的经验测试表明,当ETag或修改的头数据包含在响应中时,无论must-revalidate
头是否存在,代理总是会重新验证。
因此,must-revalidate
的目的是在它过时时强制"绕过缓存",这只有在您设置了生存期/期限时才会发生,因此,如果在没有期限或其他标头的响应上设置must-revalidate
,它实际上相当于no-cache
,因为该响应将被视为立即过时。
--所以我要最后记下吉利的答案!
我相信must-revalidate
的意思是:
缓存过期后,拒绝向用户返回过时的响应即使他们说陈旧的回应是可以接受的。
而no-cache
暗示:
must-revalidate
加上响应立即变为陈旧的事实。
如果响应可缓存10秒,则must-revalidate
在10秒后生效,而no-cache
意味着must-revalidate
在0秒后生效。
至少,这是我的理解。
max-age=0, must-revalidate
和no-cache
并不完全相同。对于must-revalidate
,如果服务器没有响应重新验证请求,则浏览器/代理应该返回504错误。使用no-cache
,它只会显示缓存的内容,这可能是用户的首选(有一些过时的东西总比什么都没有好)。这就是must-revalidate
仅用于关键事务的原因。
no-cache
的解释,我在chrome 52.0.2743.116 m下进行了测试,结果表明no-cache
与must-revalidate
具有相同的行为,当服务器无法访问时,它们都将NOT使用本地缓存,当服务器不可访问时,当点击浏览器的后退/前进按钮时,它们也都将使用缓存。如上所述,我认为max-age=0, must-revalidate
与no-cache
相同,至少在实现上是这样。
值得一提的是,HTTP验证上的MDN页面直接解决了这一问题(强调我):
人们常说CCD_ 26和CCD_ 27与CCD_。
Cache-Control: max-age=0, must-revalidate
CCD_ 29表示响应立即失效,
must-revalidate
意味着它必须一旦过期,在没有重新验证的情况下不能重复使用--所以组合,语义似乎与no-cache
相同。然而,
max-age=0
的使用是许多HTTP/1.1之前的实现无法处理no-cache
指令——因此为了处理该限制,max-age=0
被用作解决方法。但是现在已经广泛部署了HTTP/1.1性能的服务器没有理由使用
max-age=0
和must-revalidate
组合--您应该只使用no-cache
供参考(为了我们自己的个人缓存控制,呵呵)MDN页面最后一次更新是在2022年6月1日;我在2022年6月10日引用了这句话(6月8日存档)。
同意@Jeffrey Fox的部分回答:
最大年龄=0,必须重新验证,并且没有完全相同的缓存。
不同意此部分:
在没有缓存的情况下,它只显示缓存的内容,这可能是用户的首选(有一些过时的东西总比什么都没有好)。
当cache-control: no-cache
重新验证失败时,实现应该做什么只是在RFC文档中没有指定。这一切都取决于实现。它们可能会抛出类似cache-control: must-revalidate
的504错误,或者只是提供来自缓存的过时副本。
我认为max-age=0, must-revalidate
和no-cache
之间有区别:
在must-revalidate
的情况下,如果返回304 Not Modified
,则允许客户端发送If-Modified-Since
请求并从高速缓存提供响应。
在no-cache
的情况下,客户端不得缓存响应,因此不应使用If-Modified-Since
。