使用 ETag 和 Expires/Cache-control 的缓存策略,没有资产版本/ID

Posted

技术标签:

【中文标题】使用 ETag 和 Expires/Cache-control 的缓存策略,没有资产版本/ID【英文标题】:Caching strategy using ETag and Expires/Cache-control with no assets version/ID 【发布时间】:2022-01-18 22:23:09 【问题描述】:

在阅读了很多关于缓存验证器的信息后(阅读this answer on SO 后更深入地阅读),我有一个疑问,在任何地方都找不到答案。

我的用例是提供一个静态资产(一个 javascript 文件,即:https://example.com/myasset.js)以在其他网站中使用,因此搞乱他们的 Gpagespeed/gmetrix 分数最重要。 我还需要他们的用户在我每次部署新更改时收到我的静态资产的更新版本

为此,我有以下响应标头:

Cache-Control: max-age=10800
etag: W/"4efa5de1947fe4ce90cf10992fa"

简而言之,我们可以看到以下关于浏览器如何使用etag 的流程

对于第一个请求,浏览器没有 If-None-Match Request Header 的值,因此服务器将返回状态码 200(Ok)、内容本身以及带有 ETag 值的响应头。

对于后续的请求,浏览器会以If-None-MatchRequest Header的形式添加之前收到的ETag值。这样,服务器可以将此值与来自 ETag 的当前值进行比较,如果两者都匹配,则服务器可以返回 304(未修改)告诉浏览器使用文件的最新版本,或者只是 200 后跟新内容以及相关的 ETag 值。

但是,我找不到任何有关使用 Cache-Control: max-age 标头的信息以及这将如何影响上述行为,例如:

    之前 max-age 的浏览器是否会请求新的更新?这意味着我可以定义一个更高的 max-age 值(pagespeed/gmetrix 会很高兴)并强制只使用 etag 指纹进行刷新。 如果不是,那么使用etag 并向网络添加额外的比特有什么好处?

【问题讨论】:

这能回答你的问题吗? What happens when you use Cache-Control: max-age with ETags? 【参考方案1】:

    不,在max-age 过去之前,浏览器不会发送任何请求。

    使用ETag 的好处是,如果文件没有改变,你不需要将整个文件重新发送给客户端。回复将是一个小的304

请注意,您可以通过使用 stale-while-revalidate 指令实现两全其美,该指令允许在缓存以静默方式在后台重新验证资源的同时提供陈旧的响应。

【讨论】:

如果浏览器将资产保存在本地缓存中,它将执行完全相同的请求并看到返回的304,这在使用etag 验证器时可见。我错过了什么吗? @fiskolin:我不确定我是否理解你的问题,但如果没有ETag(或Last-Modified)的响应,就不会有条件请求,因此可以'不要成为304

以上是关于使用 ETag 和 Expires/Cache-control 的缓存策略,没有资产版本/ID的主要内容,如果未能解决你的问题,请参考以下文章

Youtube API V3 和 Etag

chrome 浏览器仅在使用 etag 和 last-modified-date 时才显示 200(来自磁盘缓存)

如果 ETag 不匹配,如何使用 ETag 在插入时抛出异常(除非它是 *)

ETag 与标头过期

使用 ETag 和 Expires/Cache-control 的缓存策略,没有资产版本/ID

缓存验证Last-Modifie和Etag的使用