【发布时间】:2023-03-12 23:56:01
【问题描述】:
我的目标是在浏览器的缓存中缓存图片。
当前设置
Cache-Control: public, max-age=10368000 标头附加到请求的图像以缓存图像。
此外,还附加了ETag: f5f9f1fb39790a06c5b93735ac6e2397 标头,以检查到达max-age 后图像是否已更改。
当再次请求相同的图像时,检查if-none-match 标头的值以查看图像是否已更改。如果没有,则返回304。
我正在使用 Fiddler 来检查 http 流量(注意 - 下面描述的行为在 Fiddler 之前已经发生,所以这不是问题)
Chrome 版本 - 77.0.3865.90(官方版本)(64 位)
预期行为
我预计图像将被缓存 10368000 秒。除非经过 10368000 秒,否则每次请求都会从浏览器的缓存中提供图像。一旦 10368000 秒过去了,就会向检查 Etag 的服务器发出请求。如果图片在服务端没有变化,返回304给客户端,将缓存时间再延长10368000秒。
使用谷歌浏览器的行为
- 第一次请求图像。以下是请求标头
- 图像成功返回,状态为 200。以下是响应标头
Fiddler 告诉我们请求并提供了一张图片
此外,图像被缓存的事实可以在~/Library/Caches/Google/Chrome 中看到。
- 我单击浏览器中的链接栏并按 Enter 再次请求图像。以下是请求标头
- 图像返回成功,状态为 304。以下是响应标头
Fiddler 告诉我们图片是从缓存中提供的
为什么 Chrome 只在收到 304 响应后才对图像提出额外请求并从缓存中提供它?
我看到第二次请求图像时设置了Cache-Control: max-age=0 请求标头。据我了解,这意味着 Chrome 希望在提供缓存图像之前重新验证缓存图像是否有效。但为什么呢?
网上有人说Etag 标头是 Chrome 确保图像有效的原因。即使我不包含Etag 标头,仅在第一个响应中包含Cache-Control: public, max-age=10368000,Cache-Control: max-age=0 也存在于第二个请求的标头中。
我也尝试过排除公共,将其设为私有等。我还添加了 Expires 和 Last-Modified 对,带和不带 max-age=10368000 并获得相同的行为。
此外,在开发工具中,我没有选中禁用缓存。所以缓存是启用的,这也是有意义的,因为图像是在返回 304 之后提供的。
当我没有单击链接栏并按 Enter 键,而是按刷新箭头(即 CMD + R)时,也会发生这种确切的行为。如果我硬刷新 CMD + SHIFT + R,则请求图像就像是第一次一样请求它,这是有道理的。
使用 Firefox 的行为
Firefox 完全按预期工作。
- 第一次请求图像。以下是请求标头
- 图像成功返回,状态为 200。以下是响应标头
Fiddler 告诉我们请求并提供了一张图片
此外,如果我将鼠标悬停在响应状态上,则显示 OK
- 我单击浏览器中的链接栏并按 Enter 再次请求图像。以下是请求标头
- 图像成功返回,状态为 200。以下是响应标头
但 Firefox 显示它已被缓存。
此外,Fiddler 在第二个请求中未检测到任何活动,因此图像是从 Firefox 的缓存中提供的。与 Chrome 不同,Chrome 向服务器发出另一个请求只是为了从它接收 304。
非常感谢您的宝贵时间和帮助。我非常感谢它,并愿意提供任何其他信息。真的很期待你对此的看法。
祝你有美好的一天:)
【问题讨论】:
标签: image google-chrome caching http-headers http-caching