71

我的问题是:有时浏览器会过度缓存一些资源,即使我已经修改了它们。但是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 

当“进入酒吧”时,他们清楚地缓存了它们

在此处输入图像描述

4

6 回答 6

23

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

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

于 2016-06-14T15:55:43.100 回答
20

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

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

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

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

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

于 2016-08-26T07:22:42.050 回答
16

新鲜度生命周期是根据几个标头计算的。如果指定了“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

于 2017-01-18T08:32:30.420 回答
12

默认缓存控制标头是: Private

缓存机制可以将此页面缓存在私有缓存中,然后仅将其重新发送给单个客户端。这是默认值。大多数代理服务器不会使用此设置缓存页面。

请参阅http://msdn.microsoft.com/en-us/library/ms524721%28v=vs.90%29.aspx

于 2013-01-24T09:19:46.790 回答
0

如果没有缓存控制标头,浏览器每次加载新(?)页面时都会请求资源。按 F5,您会使该页面中的任何缓存项无效(甚至在逻辑上删除),因为没有可用的本地版本,从而强制完全重新加载 - 我不确定浏览器是否在再次请求它们之前从缓存中删除了这些资源。

有趣的是,某些浏览器中有一些“附加”设置会导致一些优化,例如每次页面加载仅请求一次资源。如果您有一个图像会随着每个请求而更改,例如计数器,即使您多次使用它,您也只会看到该图像的一个版本。

下一个是浏览器通过应用某种本地“首选”缓存来重用未明确设置为 nocache 的图像。如果您希望每次需要将其设置为重新验证并将过期设置为 -1 或类似的东西时都有一个请求。

因此,根据指定的资源,通常不会触发一些默认值,这些默认值与您在阅读规范时所期望的不同。

关于源是本地、驱动器还是真正的远程 Internet 服务器,也可能存在不同的行为。据说并不是所有的浏览器都有不同的行为,我很有限。

有帮助的是查看 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 的 localhost 连接,所有发生的事情是缓存从不询问。我没有设置缓存信息等。单独指定 etag 接缝会导致 FireFox 不再请求资源。所以我遇到了与你的问题类似的事情。

于 2013-11-25T21:21:13.203 回答
0

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

于 2019-06-04T07:35:01.000 回答