将 Cache-Control: max-age 与 ETag 一起使用时会发生啥?
Posted
技术标签:
【中文标题】将 Cache-Control: max-age 与 ETag 一起使用时会发生啥?【英文标题】:What happens when you use Cache-Control: max-age with ETags?将 Cache-Control: max-age 与 ETag 一起使用时会发生什么? 【发布时间】:2021-09-06 13:50:55 【问题描述】:有几个类似的问题,但我发现没有一个是明确或明确的。
这是我想要的行为:
只要网络可用,浏览器必须检查是否有新版本 如果没有新版本,浏览器可以使用缓存的版本 缓存版本在 X 天后过期我想我可以用 Cache-Control: max-age
和 ETags 做到这一点。但是,我找不到 max-age 是否应该是 0
或者内容应该缓存多长时间。
例如如果我用 ETag 做Cache-Control: max-age=86400
(1 天),会不会:
每次都向服务器发出请求,但如果 ETag 没有更改,服务器只会返回 304。 1天后,丢弃缓存的版本,从服务器重新获取(应该与丢弃的版本相同)。
一天不发出任何服务器请求。然后,1天后,服务器仍然可以返回304。缓存的版本可以无限期保留。
我希望浏览器在 X 天后重新获取,因为万一出现错误,我不希望用户被损坏的缓存版本卡住。
【问题讨论】:
【参考方案1】:这是我想要的行为:
只要网络可用,浏览器必须检查是否有新版本 如果没有新版本,浏览器可以使用缓存的版本
这是一个常见的用例,可以通过使用Cache-Control: no-cache
(或max-age=0, must-revalidate
)并提供ETag
或Last-Modified
标头来完成。
缓存版本在 X 天后过期
这是不可能的。它不是 HTTP 缓存设计的一部分,因为它没有用例。
我希望浏览器在 X 天后重新获取,因为万一出现错误,我不希望用户被损坏的缓存版本卡住。
如果浏览器每次都检查新版本,用户怎么会被“损坏”的缓存版本卡住?
如果我用 ETag 做
Cache-Control: max-age=86400
(1 天),会不会:
每次都向服务器发出请求,但如果 ETag 没有更改,服务器只会返回 304。 1天后,丢弃缓存的版本,从服务器重新获取(应该与丢弃的版本相同)。
一天不发出任何服务器请求。然后,1天后,服务器仍然可以返回304。缓存的版本可以无限期保留。
数字 2。max-age
告诉浏览器它可以在多长时间内认为资源是新鲜的,这意味着可以使用缓存的版本而无需与服务器检查。当该时间到期时,资源将被视为陈旧,并且必须发出新请求。如果缓存的资源具有ETag
或Last Modified
标头,则该请求可以是有条件的,以允许服务器避免在响应中发送整个资源。
【讨论】:
一个用例可能是错误生成 ETag 的错误,因此即使内容更改,服务器也总是返回 304。之前我有一个错误,用户被陈旧的脚本卡住了很长时间,忘记了发生了什么 @LeoJiang:在那种情况下可能发生的事情,并且有点常见的是max-age
被设置了很长时间。这是一个真正的问题,因为此时服务器无法强制浏览器请求新版本。相反,在不正确的ETags
的情况下,服务器处于控制之中,一旦修复了错误,下一个请求就会正常工作。所以这真的不是问题。以上是关于将 Cache-Control: max-age 与 ETag 一起使用时会发生啥?的主要内容,如果未能解决你的问题,请参考以下文章
CloudFront“age”标头对“cache-control: private; max-age=3600”的影响
max-age, no-Cache,must-revalidate on Cache-Control Header,这里优先考虑哪个?
如何在 Rails 环境中使用 Cache-Control: max-age Header 来控制 Varnish 和浏览器?