来自 RFC 2616
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1
no-cache
如果 no-cache 指令未指定字段名称,则缓存
不得使用响应来满足后续请求,除非
与源服务器的重新验证成功。这允许一个原点
服务器以防止缓存,即使是已配置为的缓存
返回对客户端请求的过时响应。
因此它指示代理重新验证all回应。
将此与
必须重新验证
当收到的响应中存在必须重新验证指令时
通过缓存,该缓存不得在条目变得陈旧后使用该条目
响应后续请求而不首先重新验证它
源服务器
因此它指示代理重新验证stale回应。
特别是关于no-cache
,这就是用户代理实际上根据经验对待该指令的方式吗?
有什么意义no-cache
如果有must-revalidate
and max-age
?
看到这个评论:
http://palpapers.plynt.com/issues/2008Jul/cache-control-attributes/
no-cache
虽然这个指令听起来像是在指示浏览器不要
缓存页面,有一个微妙的区别。 “无缓存”指令,
根据 RFC,告诉浏览器应该重新验证
在从缓存中提供页面之前先调用服务器。重新验证是一个
巧妙的技术可以让应用程序节省带宽。如果
浏览器缓存的页面没有改变,服务器只是发出信号
到浏览器并且页面从缓存中显示。因此,
浏览器(至少在理论上)将页面存储在其缓存中,但是
仅在与服务器重新验证后才显示。在实践中,IE
Firefox 已经开始将 no-cache 指令视为
指示浏览器甚至不要缓存该页面。我们开始观察
这种行为大约一年前。我们怀疑这一变化是
由于该指令的广泛(且不正确)使用,
防止缓存。
有人对此有更官方的消息吗?
Update
当且仅当未能验证表示上的请求可能导致不正确的操作(例如默默地未执行的金融交易)时,服务器才应使用必须重新验证指令。
这是我迄今为止从未放在心上的事情。 RFC 表示不要轻易使用必须重新验证。问题是,对于 Web 服务,您必须采取消极的态度,并为未知的客户端应用程序假设最坏的情况。任何陈旧的资源都有可能导致问题。
我刚刚考虑过的其他事情,如果没有 Last-Modified 或 ETags,浏览器只能再次获取整个资源。然而,对于 ETags,我观察到 Chrome 至少似乎对每个请求都进行了重新验证。这使得这两个指令毫无意义,或者至少命名不当,因为它们无法正确重新验证,除非请求还包含其他标头,然后无论如何都会导致“始终重新验证”。
我只是想让最后一点更清楚。只需设置must-revalidate
但不包括 ETag 或 Last-Modified,代理只能再次获取内容,因为它没有任何内容可发送到服务器进行比较。
然而,我的经验测试表明,当响应中包含 ETag 或修改后的标头数据时,代理总是会重新验证,无论是否存在must-revalidate
header.
所以重点是must-revalidate
是在缓存过时时强制“绕过缓存”,这只有在您设置了生命周期/年龄时才会发生,因此如果must-revalidate
设置在没有年龄或其他标头的响应上,它实际上相当于no-cache
因为响应将被立即视为过时。
——所以我终于要标记吉利的答案了!