Cache-Control:max-age = 0和no-cache有什么区别?


Answers:


596

我遇到了同样的问题,并在搜索中找到了一些信息(您的问题作为结果之一出现)。这是我确定的...

Cache-Control标头有两个方面。一侧是可以通过Web服务器(也称为“原始服务器”)发送的位置。另一面是浏览器(也称为“用户代理”)可以将其发送的位置。


由原始服务器发送时

我相信max-age=0只是告诉缓存(和用户代理)响应是从一开始就过时的,因此他们应该If-Not-Modified在使用缓存副本之前重新验证响应(例如,使用标头),而no-cache告诉他们必须在使用缓存副本之前重新验证响应复制。从14.9.1开始是什么

无缓存

...如果未成功与原始服务器重新验证,则缓存不得使用响应来满足后续请求。这样,即使已配置为将陈旧响应返回给客户端请求的缓存,原始服务器也可以防止缓存。

换句话说,缓存有时可能会选择使用陈旧的响应(尽管我认为必须随后添加Warning标头),但no-cache表示无论如何都不允许它们使用陈旧的响应。在页面中生成棒球统计信息时,您可能希望应该 -revalidate行为,但是在生成对电子商务购买的响应时,您可能希望必须 -revalidate行为。

尽管说您no-cache不应该阻止存储时您的评论是正确的,但使用时实际上可能是另一个不同no-cache。我碰到了一个页面,“ Cache Control Directives Demystified”,上面写着(我不能保证它的正确性):

实际上,IE和Firefox已经开始对待no-cache指令,就像它指示浏览器甚至不缓存页面一样。大约一年前,我们开始观察这种行为。我们怀疑此更改是由于此指令广泛(且不正确)使用以防止缓存而引起的。

...

请注意,最近,“ cache-control:no-cache”也开始表现得像“ no-store”指令一样。

顺便说一句,在我看来,Cache-Control: max-age=0, must-revalidate基本上应该表示与相同的意思Cache-Control: no-cache。因此,也许这是一种获得MUST的 MEST-revalidate行为的方式no-cache,同时又避免了明显的迁移no-cache以执行与no-store(例如,不进行任何缓存)相同的操作?


由用户代理发送时

我相信shahkalpesh的答案适用于用户代理方。您也可以查看13.2.6消除多个响应的歧义

如果用户代理发送带有Cache-Control: max-age=0(又称为“端到端重新验证”)的请求,则沿途的每个高速缓存将If-Not-Modified一直对原始服务器重新验证其高速缓存条目(例如,带有标头)。如果答复是304(未修改),则可以使用缓存的实体。

另一方面,使用Cache-Control: no-cache(也称为“端到端重载”)发送请求不会重新验证,并且服务器在响应时务必不要使用缓存的副本。


9
Cache-Control不会:max-age = 0,必须重新验证,代理重新验证是否等同于no-cache吗?
Didier A.

1
很好的答案,我去阅读了您网站上的文章,但该页面不再有效。 palisade.plynt.com/issues/2008Jul/cache-control-attributes
Craig London

7
谢谢,@ CraigLondon。我将其重定向到缓存的版本。
Michael Krebs 2015年

2
must-revalidate并非与no-cache或相同no-store。后者完全绕过了缓存,但是前者只是说必须始终检查缓存的新鲜度,但是如果它仍然是最新的,则可以使用它,从而节省了带宽。后者强制始终进行完整的端到端下载,占用不必要的带宽并延迟响应。
Patanjali

3
@Patanjali no-cache 不会 “完全绕过缓存”或“一直一直强制进行完整的端到端下载”,至少不是在所有浏览器中都如此。该规范仅表示浏览器必须验证缓存。
富兰克林·于

57

最大年龄= 0

这等效于单击Refresh,这意味着给我最新的副本,除非我已经拥有最新的副本。

无缓存

这是在按住Shift的同时单击“刷新”,这意味着无论如何都可以重做所有操作。


31
这是不正确的。shift-refresh是硬刷新,它与no-store
Michael

3
在Firefox 45.0中进行了验证,例如Chrome 49.0.2623.87 m,在Shift + Refreshing时也会发送“ Pragma:no-cache”。
Cees Timmerman

34

现在是一个老问题,但是如果其他人像我一样通过搜索遇到此问题,则似乎IE9将在使用后退和前进按钮时利用此来配置资源的行为。当使用max-age = 0时,浏览器在后退/前进时查看资源时将使用最新版本。如果使用no-cache,将重新获取资源。

有关IE9缓存的更多详细信息,请参阅此msdn缓存博客文章


4
类似地,当通过https使用无缓存时,IE 8会遇到各种各样的“无法下载”问题。建议的解决方案有时包括将标头更改为max-age = 0
罗伯特·

28

在我最近对IE8和Firefox 3.5的测试中,似乎两者都符合RFC。但是,它们与原始服务器的“友好性”不同。IE8 no-cache使用与相同的语义处理响应max-age=0,must-revalidate。但是,Firefox 3.5似乎与no-cache等效no-store,这会降低性能和带宽使用率。

默认情况下,Squid Cache似乎从不存储任何带有no-cache标头的内容,就像Firefox一样。

我的建议是为public,max-age=0希望在每个请求中检查新鲜度的非敏感资源设置,但仍然允许缓存具有性能和带宽优势。对于具有相同考虑因素的每用户项目,请使用private,max-age=0

我会避免使用no-cache完全,因为似乎它已被某些浏览器和流行的缓存所混为一谈,其功能等效于no-store

此外,请勿模仿Akamai和Limelight。尽管他们本质上将大型缓存阵列作为主要业务运行,并且应该是专家,但实际上他们对使更多数据从其网络下载具有浓厚的兴趣。Google可能也不是模仿的好选择。他们似乎根据资源使用max-age=0no-cache随机使用。


2
密码保护内容的最佳答案。private,max-age=0
dana 2014年

21
最大年龄
    当强制中间高速缓存时,通过max-age = 0指令重新验证 
自己的缓存条目,并且客户端在请求中提供了自己的验证器, 
提供的验证器可能不同于当前与高速缓存条目一起存储的验证器。 
在这种情况下,缓存可以使用任何一个验证器来发出自己的请求,而无需 
影响语义透明性。 

    但是,验证器的选择可能会影响性能。最好的方法是
中间缓存在发出请求时使用其自己的验证器。如果服务器回复
304(未修改),则缓存可以将其现在已验证的副本返回给客户端 
响应为200(OK)。如果服务器回复了新的实体和缓存验证器,
但是,中间缓存可以将返回的验证器与中提供的验证器进行比较。 
客户的要求,使用强大的比较功能。如果客户的验证人是
等于原始服务器的,则中间缓存仅返回304(不是 
改性)。否则,它将返回带有200(OK)响应的新实体。

    如果请求包含no-cache指令,则不应包含min-fresh, 
最大过时或最大年龄。 

礼貌:http : //www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4

不接受此作为答案-我将不得不阅读它以了解其真正用法:)


12

我几乎不是缓存专家,但Mark Nottingham是。这是他的缓存文档。他在“参考”部分也有出色的链接。

根据我对这些文档的阅读,看起来max-age=0可以允许缓存将缓存的响应发送给在“相同时间”出现的请求的缓存响应,其中“相同时间”意味着足够接近,它们看起来与缓存同时存在,但是no-cache不会。


好点,但是实际上任何浏览器实际上都可以做到吗?
Pacerier

3
@Pacerier我认为这更适用于缓存Varnish,Squid,Traffic等代理服务器
Hank Gay

12

顺便说一句,值得注意的是,某些移动设备,特别是iPhone / iPad之类的Apple产品完全忽略了诸如无缓存,无存储,Expires:0之类的标头,或者您可能试图迫使它们不重复使用的任何其他方法表单页面。

这一直没有引起我们头痛,因为我们试图让用户的iPad发出问题,即他们在通过表单处理(例如3的第2步)到达的页面上处于睡眠状态,然后设备完全忽略了商店/据我所知,cache指令只是从页面的最后状态开始获取页面的虚拟快照,也就是说,忽略显式告诉的内容,不仅如此,还应获取不应存储的页面,并在没有实际检查的情况下进行存储,这会导致各种奇怪的会话问题,以及其他问题。

我只是添加此信息,以防有人出现而无法弄清楚为什么他们在使用iphone和ipad时会出现会话错误,这似乎是该领域最严重的违规者。

我已经针对此问题进行了相当广泛的调试器测试,这是我的结论,设备将完全忽略这些指令。

即使在常规使用中,我也发现有些手机也完全无法通过说Expires:0来检查新版本,然后检查上次修改的日期来确定是否应该获得一个新版本。

它根本不会发生,所以我被迫要做的是向强制更新的css / js文件中添加查询字符串,这使愚蠢的移动设备认为它是一个没有的文件,例如:my .css?v = 1,然后v = 2进行css / js更新。这在很大程度上起作用。

顺便说一句,用户浏览器也一直保持默认状态(截至2016年),因为我不断发现(我们对网站做了很多更改和更新)也无法检查此类文件的最后修改日期,但是查询字符串方法可解决该问题。这是我在客户端和办公人员中注意到的,这些人员和办公人员倾向于在其浏览器上使用基本的普通用户默认设置,并且不了解css / js等的缓存问题,几乎总是无法获得更改后的新css / js,这意味着其浏览器(主要是MSIE / Firefox)的默认设置没有执行其指示的操作,它们忽略更改并忽略最后修改的日期,并且即使使用Expires:0进行了显式设置,也不会进行验证。

这是一个很好的线程,提供了很多很好的技术信息,但也必须注意,特别是在移动设备中,对此类工具的支持有多糟糕。每隔几个月,我必须添加更多保护层,以防止它们无法遵循收到的标头命令或正确干扰这些命令。


css和js是适合缓存的候选对象,因为在生产系统中,它们实际上不应经常更改。但是,在开发过程中为它们进行缓存是很痛苦的,因为该活动可能需要频繁强制缓存。但是,如果不能针对不同的环境使用不同的设置,则应优先考虑生产要求,因为它的影响最大,因为与少数开发人员拥有的Ctrl-F5刷新次数相比,访问量大得多将节省带宽去做。但是,查询实时数据要求缓存控制正常工作。
Patanjali

0

令人惊讶的是,未提及的一件事是,使用该max-stale指令,请求可以显式表明它将接受陈旧数据。在那种情况下,如果服务器以响应max-age=0,则缓存将仅考虑响应过期,并且可以自由使用它来满足客户端的请求(该请求要求潜在的过期数据)。相比之下,如果服务器发送的no-cache确实确实胜过客户端(带有max-stale)对陈旧数据的任何请求,则必须重新验证缓存。


-2

区别在于,无缓存(Firefox上无存储)可防止任何类型的缓存。这对于防止将包含安全内容的页面写入磁盘以及即使应使用“后退”按钮重新访问的页面也应始终进行更新的页面很有用。

max-age = 0表示高速缓存条目是陈旧的,需要重新验证,但不阻止高速缓存。通常,浏览器在每个浏览器会话中仅验证一次资源,因此,只有在新会话中访问该网站后,内容才会更新。

通常,浏览器不会删除过期的缓存条目,除非它们在浏览器缓存已满时为新内容回收空间。使用no-store,no-cache允许显式删除缓存条目。


9
据我了解,“ no-cache”不应阻止存储(“ no-store”是实现存储的正确方法)。某些浏览器是否将“无缓存”解释为“无存储”?这可以解释为什么使用“ max-age = 0”代替“ no-cache”
rubyruy

3
错了 往上看。某些浏览器/服务器可能选择将无缓存实现为无存储,但不是全部。
杰里米·考夫曼

4
唯一安全的方法是使用,max-age=0如果您的意思是允许缓存,但是应该重新验证资源,no-store并且您根本不希望将响应存储在缓存中。在no-cache随机指定为是指这些取决于用户代理供应商和版本号和传输协议。
Mikko Rantalainen 2012年

Firefox何时使用无存储?
Cees Timmerman
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.