4

我们有几个文件通过 HTTP 提供,并且不时更改。

哪些是与缓存相关的 HTTP 标头,我们应该在 HTTP 响应中返回以优化浏览器加载速度,同时强制浏览器验证它是否具有文件的最新版本?

我们已经设置了一个带有过去日期的“Expires”标题(此时似乎达成了共识)。

但是有些人建议设置此标头:

Cache-Control: no-cache, no-store, must-revalidate

但是这个头的问题是它阻止了浏览器保留文件的本地副本,所以每次下载文件,即使它没有改变,也有 200 响应代码。

如果我只是使用:

Cache-Control: no-cache

然后浏览器(至少 Firefox 14 和 Chrome 20)保留本地副本,发送If-Modified-SinceIf-None-Matchheaders,服务器返回 304 代码并且文件内容没有下载。 这是这些文件可以随时更改的最佳行为。

问题是我不知道仅设置“无缓存”是否足以强制所有浏览器(包括旧但仍在使用的版本)和代理服务器使用服务器重新验证其本地缓存的副本。

最后,Pragma: no-cache标题呢?它也应该包含在 HTTP 响应中吗?

4

3 回答 3

5

Google 开发人员文档有一个很好的缓存文档,并提供了一些很好的使用模式。

例如,它有一个用于定义最佳缓存控制策略的流程图。

在此处输入图像描述

此外,它定义了一个很好的模式来为文件添加指纹并设置更长的期限,例如一年。

  • 使用本地缓存的响应,直到资源“过期”
  • 在 URL 中嵌入文件内容指纹使我们能够强制客户端更新到新版本的响应
  • 每个应用程序都需要定义自己的缓存层次结构以获得最佳性能

在此处输入图像描述

定义每个资源缓存策略的能力允许我们定义“缓存层次结构”,它不仅允许我们控制每个缓存的时间长度,还可以控制访问者看到新版本的速度。例如,我们来分析上面的例子:

  • HTML 标有“无缓存”,这意味着浏览器将始终在每次请求时重新验证文档,并在内容发生更改时获取最新版本。此外,在 HTML 标记中,我们将指纹嵌入到 CSS 和 JavaScript 资产的 URL 中:如果这些文件的内容发生变化,那么页面的 HTML 也会发生变化,并且将下载 HTML 响应的新副本。
  • CSS 允许被浏览器和中间缓存(例如 CDN)缓存,并设置为 1 年到期。请注意,我们可以
    安全地使用 1 年的“远期到期”,因为我们将文件
    指纹嵌入其文件名:如果 CSS 更新,URL 也会改变
  • JavaScript 也设置为 1 年后到期,但被标记为私有,可能是因为它包含一些
    CDN 不应缓存的私有用户数据。
  • 该图像在没有版本或唯一指纹的情况下被缓存,并设置为 1 天后过期。

ETag、Cache-Control 和唯一 URL 的组合使我们能够提供所有世界中最好的:长期有效的到期时间、控制可以缓存响应的位置以及按需更新

于 2015-01-28T12:12:14.430 回答
1

最好的方法,也许不是 100% 满足您的需求是:

Cache-Control:max-age=315360000, public
Expires:Tue, 23 Aug 2022 10:53:13 GMT

并给文件一个“依赖于内容的文件名”,例如 stylesheet_v32.css。一旦内容发生变化,更改文件名+引用,浏览器就会获得最新版本。如果文件名保持不变,则浏览器不需要请求它。

这在所有浏览器中都是安全且一致的。

无论如何,依靠Cache-Control: no-cache浏览器保存它是我不想做的。

于 2012-08-25T10:57:37.413 回答
0

我找到了两种强制客户端重新检查缓存的方法:

Cache-Control: max-age=0, must-revalidate
Expires: Thu, 01 Jan 1970 00:00:00 GMT

这至少适用于 Firefox。我想 IE 和 Chrome 也会做出正确的反应。它应该适用于使用 HTTP/1.0 的旧浏览器。

使用 HTTP 1.1,您可以使用ETag. 在这种情况下,该must-revalidate选项不是必需的,因为拥有ETag足以让客户做出反应,就好像must-revalidate在那里:

Cache-Control: max-age=0
ETag: 123
Expires: Thu, 01 Jan 1970 00:00:00 GMT

这将告诉客户端使用ETag123 创建数据的缓存版本,并在每次需要该数据的副本时重新检查服务器。然后,您可以使用 回复304 Not Modified

绝对不能使用的两个选项是:no-cacheno-store.

如果要防止中间缓存缓存数据,请确保添加privateCache-Control选项中。

作为一个有趣的功能,您还可以使用一个小的 max-age,例如几分钟,让客户端在这段时间内缓存数据,然后发送一个GET您可以回答的 a 304

Cache-Control: max-age=300
ETag: 123
Expires: Tue, 29 Mar 2015 15:05:00 GMT

在这种情况下,预计浏览器将在 5 分钟内不检查新数据。之后,它会向您发送If-None-Match: 123.

于 2016-03-29T22:01:09.380 回答