简而言之:
假设
s-maxage
是一天,max-age
是一小时。代理缓存将保留资源一天,但几个小时后,Age
标头将超过一个小时。浏览器看到资源早于一小时,不会在本地缓存它。无论如何如何将其缓存在浏览器本地?
我正在尝试将
Cache-Control: max-age
和 s-maxage
与合理的值结合起来。
但设置s-maxage > max-age
似乎没有意义。
最终,浏览器将始终重新验证资源并跳过本地浏览器缓存,因为从代理缓存接收到的资源将立即过时 (Age > max-age
)。
目标:
s-maxage
),必要时可以清除。max-age
)。问题:
资源会在代理缓存中保留很长时间 (
s-maxage
),而其 Age
会增加(自从源获取以来的时间)。
最终缓存中资源的Age
将大于max-age
。
当发生这种情况时,浏览器将在每次需要资源时重新验证,因为资源在每次请求时都是陈旧的。
例如:
Cache-Control: max-age=60, s-maxage=86400
。
浏览器应将资源保留 60 秒。代理缓存将资源保留一天。
t=0
browser: need resource
proxy cache: fetch resource from origin
-> cache returns fresh resource with Age: 0 / Cache-Control: "max-age=60, s-max-age=86400"
t=30
browser: locally cached resource is still fresh: Age (0+30) < max-age (60)
t=70
browser: local cache is stale: Age (0+70) > max-age (60) -> revalidate
proxy cache: cached resource is still fresh: Age (70) < s-maxage (86400)
-> cache returns resource with Age: 70, Cache-Control: "max-age=60, s-maxage=86400"
缓存返回的资源的
Age (70)
大于 max-age (60)
。
从现在开始,每次浏览器需要该资源时,该资源都会在本地过时并需要重新验证。
t=75
browser: local cache is stale: Age (70+5) > max-age (60) -> revalidate
proxy cache: cached resource is still fresh: Age (75) < s-maxage (86400)
-> cache returns resource with Age: 75 / Cache-Control: "max-age=60, s-max-age=86400"
这意味着,如果资源在代理缓存中的时间超过
max-age
,浏览器将始终重新验证。
max-age
值仅在从源获取新资源后的 max-age
秒内有用。
设置
s-maxage > max-age
好像没有意义。
你的分析看起来是正确的,我想我同意。具体来说,给定特定的
s-maxage
值,很难看出为什么要使用较小的 max-age
,因为这将导致毫无意义的条件验证请求。
请注意,设置
max-age > s-maxage
有合理的用例,因此协议将它们定义为两个单独的指令仍然有意义。
如何强制浏览器在收到资源后将其缓存特定时间,无论其新鲜度如何(如
Age
标头所示)?
HTTP 缓存基于资源的寿命,而不是恰好收到响应的时间。因此无法强制用户的浏览器或代理缓存执行此操作。
但是我的缓存计划是完全合理的:我想将
max-age
设置为一个小值,以准确表示我可以容忍的陈旧程度,但将s-maxage
设置为一个长值,并在代理缓存失效时简单地使代理缓存失效。资源变化。为什么 HTTP 规范不支持这一点?
这里的根本问题是,您的(确实是完全合理的)缓存方案依赖于对代理缓存的控制(以强制失效),而 HTTP 定义的互联网架构基于源服务器没有的独立参与者掌控。您所描述的代理缓存最好被视为“托管缓存”。 MDN对此有一个有用的讨论:
共享缓存可以进一步细分为代理缓存因此,如果您使用托管缓存(Cloudfront 等),则根本不需要使用和托管缓存....托管缓存由服务开发人员显式部署以卸载源服务器并有效地交付内容....
在大多数情况下,您可以通过
Cache-Control
标头和您自己的配置文件或仪表板 控制[托管]缓存的行为。例如,HTTP 缓存规范本质上没有定义显式删除缓存的方法,但使用托管缓存,可以通过仪表板操作、API 调用、重新启动等随时删除存储的响应。这允许更主动的缓存策略。
s-maxage
来管理缓存。您可以直接控制 HTTP 协议之外的设置。
即使我使用设置来控制托管缓存保留期限,我仍然面临Age
标头强制浏览器重新验证的问题。与托管缓存公开 TTL 设置的方式相同,它也可以公开在每个响应上发送新的
Age
标头的能力。我不知道是否有任何特定的托管缓存解决方案可以做到这一点。