我修改了网站中的 js 和 css 文件。但浏览器仍然从本地缓存中获取内容,因为浏览器已存储了它。我想从服务器获取最新内容而不清除本地缓存。以前 max-age 标头设置为 1 年。现在我将其设置为 0。它仍然没有获取最新内容。
有没有什么办法可以将标头从服务器发送到浏览器,然后它会获取新内容,而忽略存储在本地缓存中的以前文件。
谢谢
答案1
您可以使用Clear-Site-Data
标头。它非常具有破坏性,因为它会删除全部缓存资源,并且根据您用于标题的值,它也可能会清除 cookie 和其他数据。
如果您使用类似的标题,Clear-SiteData: "cache"
那么您将仅清除缓存。
在撰写本文时,该"cache"
值仅受 Chrome 和 Edge 支持。
答案2
发送Cache-control: no-cache
以告知接收浏览器释放缓存条目。这必须针对缓存中的每个对象发送,因此最好使用脚本来完成。
答案3
如果浏览器已缓存资源,且缓存时间尚未到期,则无法强制其重新加载资源。这正是缓存的本质 - 指示在这段时间内可以安全地使用资源。
您不能只添加缓存标头,并期望已经下载该资产的浏览器获取这些新标头 - 它们不会在具有有效缓存版本时下载该文件!唯一的例外是用户执行重新加载(Chrome 中的 F5)或强制重新加载(Chrome 中的 Ctrl+F5)。
有各种缓存爆发类型和技术,这涉及更改资产的引用(例如,您将页面从引用 main.css 更新为 main_v2.css,或 main.css?version=2)。这取决于实际页面未被缓存。我个人认为这有点浪费(有多少人从主页开始,然后点击一个页面,然后返回主页并至少需要 304 重新验证?)所以我更喜欢仍然缓存页面,但使用较短的有效期,但这是另一个问题。
所有这些问题的答案似乎是使用标must-revalidate
头,但成功的缓存策略既可以防止重新下载可缓存资产,也可以防止对其进行检查。这些检查调用(如果文件在服务器上仍相同,则会导致“304 未修改”响应,而不是完全下载)确实需要花费大量时间,尤其是当页面中有大量资产时,因此使用它们只能解决一半的问题 - 最好在给定的时间段内完全缓存,然后在该时间之后使用 304 重新验证。
一个更有趣的缓存控制选项是重新验证时过期,例如,它允许您将资产缓存 1 小时,但可以在浏览器下次在后台重新验证资产时再重复使用 2 小时。因此,这提供了一种重新验证和更新机制,而无需每次都提前检查,从而降低性能。但是,目前还没有浏览器支持此功能(通过铬合金和火狐已经看过了。
最后,您的问题中的一条评论建议使用 HTTP/2 来推送新资产。这在理论上很好,但是HTTP/2 推送不是这样工作的(尽管有人建议也许应该这样做——正是出于这个原因)。相反,HTTP/2 推送会维护自己的“推送缓存”,然后浏览器在需要时将项目加载到其“主缓存”中。但它总是先检查自己的“主缓存”,除非其中不存在,否则不会检查“推送缓存”。所以它基本上是“主缓存”、“推送缓存”、“服务器”的优先级顺序,并使用第一个有效命中。