为什么浏览器没有遵守Cache-Control头部信息?

4
我在S3上有一个带有“Cache-Control”头设置为“public,max-age = 3600”的图像。因此,下游系统(代理,浏览器等)应该将其缓存1小时。
我可以看到浏览器在后续请求之后返回304(未修改)。
然后我去更新了S3上的图像(资源未经版本控制... URL未更改,只是内容更改),但浏览器获取了新版本。(例如HTTP 200)。
以下是Chrome网络流量:

enter image description here

请求:

  1. 200 (ok) - 成功
  2. 304 (not modified) - 未修改

~ 图像在幕后更改 ~

  1. 200 (ok) - 成功
  2. 304 (not modified) - 未修改

这是响应头: enter image description here

这怎么可能?我没有设置正确的标头吗?

有两件事让我感到困惑:

  1. 响应仍应该是304(未修改)吗?浏览器如何知道去获取图像? max-age还没有达到?
  2. Chrome不应该显示“来自磁盘缓存”或类似的东西吗?(而不是实际上去服务器?)

我的猜测是-我没有设置正确的缓存控制标头之类的东西。那么,有人可以解释一下这种行为,并让我知道我需要做些什么才能缓存资源1小时:)

谢谢!


尽管@zerkms给出了一个很棒的答案,但是这个不错的SO回答为故事增加了一些不错的额外背景:https://dev59.com/1l8e5IYBdhLWcg3wCGu_#26339940 - Pure.Krome
1个回答

3

响应中指定了ETag

规范中解释了ETag

在无法存储修改日期、HTTP日期值的一秒分辨率不足以满足要求或修改日期不一致的情况下,实体标记可以比修改日期更可靠地进行验证。

因此,浏览器优先选择它而不是基于日期的过期。

因此,您的浏览器每次都会发出请求,除非内容已更改 - 返回http 304。否则 - 是http 200。

如果您只想使用基于时间的到期 - 请删除ETag

参考资料:


啊..我怀疑是ETag的问题。那么它优先吗?例如,如果ETag已更改,它会获取图像,尽管max-age仍在有效期内?基本上,如果您有ETag,则设置max-age没有任何意义。 - RPM1984
@RPM1984 它每次都发出请求,而不考虑 max-age - zerkms
如果您有一个ETag,甚至设置max-age也没有意义。是的,我会这么说。 - zerkms
但是为什么即使返回 304 状态码,我的浏览器仍然会访问服务器呢?它不应该显示“来自磁盘缓存”吗?(例如我的问题中的第二点)。在什么条件下它才不会去服务器请求数据呢? - RPM1984
@RPM1984 存在 ETag 使其每次都会执行。"它不应该说(来自磁盘缓存)吗?" --- 不应该,因为响应是从带有 HTTP 304 的服务器提供的,只有内容来自磁盘缓存。HTTP 304 意味着内容来自缓存。 - zerkms

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