根据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-revalidate
和max-age
,那么no-cache
有什么意义?
请参阅此评论:
http://palpapers.plynt.com/issues/2008Jul/cache-control-attributes/
这是一种巧妙的技术,可以让应用程序节省带宽。如果浏览器缓存的页面没有更改,服务器会向浏览器发送信号,页面将从缓存中显示。因此,浏览器(至少在理论上)将页面存储在其缓存中,但仅在与服务器重新验证后才显示该页面。实际上,IE和Firefox已经开始将no-cache指令视为指示浏览器甚至不要缓存页面。我们大约一年前开始观察到这种行为。我们怀疑这种变化是由于广泛(并且不正确)使用此指令来防止缓存而引起的。no-cache
尽管此指令听起来像是在指示浏览器不要缓存页面,但这是一个微妙的区别。根据RFC,"no-cache"指令告诉浏览器应该在从缓存中提供页面之前与服务器重新验证。重新验证是一种机制,可让缓存在相同时间内返回新数据而无需在每个请求上都去检查源服务器。
有人有更正式的信息吗?
更新
必须重新验证指令只有在不验证表示时请求可能导致错误操作(例如静默未执行的金融交易)时,服务器才应使用。
直到现在我才真正认真对待这件事。RFC是说不要轻易使用must-revalidate。问题是,在Web服务中,您必须采取负面视角,并为未知的客户端应用程序假定最坏的情况。任何过时的资源都有可能引起问题。
我刚才考虑了另一件事,在没有Last-Modified或ETags的情况下,浏览器只能再次获取整个资源。但是,使用ETags,我观察到至少Chrome似乎在每个请求上重新验证。这使得这两个指令毫无意义,或者至少命名不当,因为除非请求还包括其他标头,否则它们无法正确重新验证。
我只想让最后一点更清楚。只需设置must-revalidate,但不包括ETag或Last-Modified,代理程序只能再次获取内容,因为它没有任何东西发送到服务器进行比较。
然而,我的实证测试表明,当响应中包含ETag或modified标头数据时,代理程序始终重新验证,而不管是否存在must-revalidate标头。
因此,must-revalidate
的目的是在缓存失效时强制执行“绕过缓存”,这只有在设置了生命周期/年龄时才会发生。因此,如果在没有年龄或其他标头的响应上设置了must-revalidate
,那么它实际上变成等效于no-cache
,因为响应将立即被视为过期。-- 因此,我最终会标记Gili的答案!