缓存控制的默认值是什么?

89

我的问题是:有时浏览器会过度缓存一些资源,即使我已经对它们进行了修改。但是在按下F5之后,一切都正常了。

我研究了整个下午的案例。现在我完全理解了"Last-Modified"或"Cache-Control"的重点,并且知道如何解决我的问题(只需使用.js?version或明确的max-age=xxxx)。但是问题仍未解决:浏览器如何处理没有"Cache-Control"的响应头,就像这样:

Content-Length: 49675
Content-Type: text/html
Last-Modified: Thu, 27 Dec 2012 03:03:50 GMT
Accept-Ranges: bytes
Etag: "0af7fcbdee3cd1:972"
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Date: Thu, 24 Jan 2013 07:46:16 GMT 

当“进入酒吧”时,他们显然会将它们缓存。

输入图像描述


1
没有默认值。该响应头不提供Expires: [a date]Cache-Control: max-age=[seconds]。因为它没有提供任何提示,客户端将使用它喜欢的任何启发式方法(例如,缓存5分钟)。这完全由客户决定,包括查看Last-Modified日期,猜测内容可能有效的时间长度。如果您没有指定任何内容:您没有任何承诺。(https://dev59.com/PWcs5IYBdhLWcg3wXi1D#49637255) - Ian Boyd
请参见 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Caching#heuristic_caching,了解有关启发式缓存的更多信息。 - mb21
6个回答

24
新鲜度寿命是基于多个标头计算得出的。如果指定了“Cache-control: max-age=N”标头,则新鲜度寿命等于N。如果未出现此标头(这种情况非常常见),则检查是否存在Expires标头。如果存在Expires标头,则其值减去Date标头的值确定新鲜度寿命。最后,如果两个标头都不存在,则查找Last-Modified标头。如果存在此标头,则缓存的新鲜度寿命等于Date标头的值减去Last-modified标头的值除以10。
来源:https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#Freshness

新鲜度只是缓存的一个因素。不能保证这是导致缓存被使用的因素。顺便提一下,此链接可以在英文版本中不使用国际化。 - Luke Exton
没有规定说只有在设置缓存控制或过期时间时才会缓存文件。收到状态码为200、203、206、300、301或410的响应可能会被缓存并用于回复后续请求,但要遵守过期机制,除非缓存控制指令禁止缓存。 - kouut
缓存常见问题解答的链接似乎已经不存在了。下次请参考英文页面。 - robsch
所以基本上,距离上次修改时间越长,浏览器重新获取资源的频率就越低? - Drazen Bjelovuk
更多关于新鲜度启发式的信息,请参阅:https://www.rfc-editor.org/rfc/rfc7234#section-4.2.2 - undefined

24

RFC 7234详细说明了浏览器和代理默认应该做什么:

尽管缓存是HTTP的完全可选功能,但可以假定重用缓存响应是可取的,并且当没有要求或本地配置阻止它时,这种重用是默认行为。因此,HTTP缓存需求侧重于防止缓存存储不可重用的响应或不当地重用已存储的响应,而不是强制缓存始终存储和重用特定的响应。


21

浏览器通常默认启用缓存,因此可以使用cache-control来自定义此行为或禁用它。

虽然缓存是HTTP的完全可选功能,但可以认为重用缓存响应是可取的,并且当没有要求或本地配置阻止时,这种重用是默认行为。因此,HTTP缓存要求侧重于防止缓存存储不能重用的响应或不适当地重用存储的响应,而不是强制缓存始终存储和重用特定响应。[https://www.rfc-editor.org/rfc/rfc7234#section-2]

浏览器认为缓存响应仍然“新鲜”的时间通常与上次修改时间有关:

由于源服务器并不总是提供明确的到期时间,因此在未指定显式时间时,缓存可以分配一种启发式到期时间,采用使用其他标题字段值的算法(例如最后修改时间)...如果响应具有Last-Modified头字段(参见[RFC7232]的第2.2节),则鼓励缓存使用不超过该时间间隔某个分数的启发式到期值。该分数的典型设置可能是10%。[https://www.rfc-editor.org/rfc/rfc7234#section-4.2.2]

这篇帖子详细介绍了不同浏览器如何计算该值。


12

1
  1. 为什么我在响应头中看不到 Cache-Control: Private?
  2. max-age = ?
- rhapsodyn
15
这并没有回答这个问题。它只是回答了在IIS 6中的默认设置是什么。 - SilverlightFox
3
这是真正的答案:https://webmasters.stackexchange.com/questions/111298/what-happens-if-you-dont-set-cache-control-header - Juraj Martinka

0
没有缓存控制头,浏览器每次加载新页面都会请求资源。按 F5 键会使该页面中的任何缓存项无效(甚至逻辑上删除),强制完全重新加载,因为似乎没有本地版本可用 - 我不确定浏览器是否在再次请求这些资源之前从缓存中删除它们。
有趣的是,某些浏览器中还有一些“额外”的设置,可以导致某些优化,例如仅在每次加载页面时请求资源一次。如果您有一个每次请求都会更改的图像,例如计数器,即使多次使用也只会看到此图像的一个版本。
接下来,浏览器通过应用某种本地的“首选”缓存重用未明确设置为 nocache 的图像。 如果您想要每次请求,请将其设置为重新验证并将过期时间设置为-1或类似内容。
因此,根据资源的不同,指定未设置的内容通常会触发一些默认设置,这些默认设置与从规格中读取的不同。
关于源是否显示为本地、驱动器或真实的远程互联网服务器,可能也会有不同的行为。可悲的是,并非所有浏览器都有不同的操作方式,而且我的选择也很有限。
有帮助的是查看 www.google.com 并查找其页面请求的跟踪像素(从 metrics.gstats.com 请求两个 1x1 像素,并在子域上使用随机部分)。
如果您使用 firebug 检查标头,您会发现它们以任何可能的方式指定了 nocache 指令。标头读起来像这样:
Alternate-Protocol  443:quic
Cache-Control   no-cache, must-revalidate
Content-Length  35
Content-Type    image/gif
Date    Mon, 25 Nov 2013 14:33:30 GMT
Expires Fri, 01 Jan 1990 00:00:00 GMT
Last-Modified   Tue, 14 Aug 2012 10:47:46 GMT
Pragma  no-cache
Server  sffe
X-Content-Type-Options  nosniff
X-Firefox-Spdy  3
X-XSS-Protection    1; mode=block

尝试将此设置为检查是否解决了浏览器未获取更改资源的问题。must-revalidate指令将导致代理缓存每次请求资源并检查304 Not Modified回复。

我目前遇到类似的情况。我有一个本地主机连接设置etag,所有发生的事情都是缓存从未询问。我没有设置缓存信息或类似信息。仅指定etag似乎会导致FireFox不再请求资源。因此,我遇到了与您的问题类似的问题。


no-cache已经意味着每次都必须重新验证。因此,在这种情况下,只需要使用no-cache即可。 - Klimashkin
关于“没有缓存控制头,浏览器每次加载新页面时都会请求资源”的问题,这似乎不适用于Google Chrome。它似乎会无限期地缓存这些项目。(我不确定其他浏览器是否也是如此。) - Sam
按下 F5 键会使页面中的任何缓存项无效(甚至逻辑上删除),从而强制重新加载。这不是正确的做法。这只会导致浏览器检查更新的资源,而不是使当前缓存无效。但是,当按下 Ctrl + F5 组合键时,某些浏览器可以执行此操作。 - SilverlightFox

0
在您的情况下,响应头中有Etag: "0af7fcbdee3cd1:972",因此它也被缓存了。

只有在发送匹配的ETag的If-None-Match时,即使匹配,它也会返回304未修改。 - tjmoore

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接