【发布时间】:2013-08-11 12:21:56
【问题描述】:
来自 RFC 2616
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1
无缓存
如果 no-cache 指令未指定字段名,则缓存 不得使用响应来满足后续请求 与源服务器成功重新验证。这允许原点 服务器以防止缓存,即使是已配置为的缓存 对客户端请求返回陈旧的响应。
因此它指示代理重新验证所有响应。
对比一下
必须重新验证
当 must-revalidate 指令出现在收到的响应中时 通过缓存,该缓存在它变得陈旧后不得使用该条目 响应后续请求,而无需先重新验证它 源服务器
因此它指示代理重新验证陈旧响应。
特别是关于no-cache,用户代理实际上是这样对待这个指令的吗?
如果有must-revalidate 和max-age,那么no-cache 有什么意义?
看到这条评论:
http://palpapers.plynt.com/issues/2008Jul/cache-control-attributes/
无缓存
虽然这个指令听起来像是在指示浏览器不要 缓存页面,有一个细微的差别。 “无缓存”指令, 根据 RFC,告诉浏览器它应该重新验证 服务器在从缓存中提供页面之前。重新验证是一个 让应用程序节省带宽的巧妙技术。如果 浏览器缓存的页面没有改变,服务器只是发出信号 到浏览器,页面从缓存中显示。因此, 浏览器(至少在理论上)将页面存储在其缓存中,但是 仅在与服务器重新验证后才显示。在实践中,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
标签: http cache-control