按资源映射策略,而非按服务器
在更改头部之前清点具有代表性的 URL:主页、内容页、应用壳、CSS、JavaScript、图片、字体、API、登录、账户、结账和下载。对每个 URL 记录该响应是公共还是个性化、其 URL 在字节变化时是否会变化,以及修正需要多快到达访客。
根据该清单制作策略矩阵。公共的、基于内容地址(content-addressed)的资产需要与稳定地址上的 HTML 不同的规则。没有 Cache-Control 的响应仍可能被启发式缓存,因此明确规则更容易测试。
存储的响应可重用的时段;max-age 以秒为单位指定该时长。
精确使用 Cache-Control 术语
Cache-Control 告诉浏览器和共享缓存如何存储与重用响应。max-age=N 在资源“新鲜”时允许重用。s-maxage=N 设置共享缓存的新鲜期并在共享缓存中覆盖 max-age,但浏览器会忽略 s-maxage。public 允许任何缓存存储;private 允许浏览器缓存但阻止共享缓存存储。
no-cache 允许存储但在重用前要求向源站验证。no-store 表示缓存不得存储该响应,但它并非完整的隐私控制。当过期后不能接受返回过期内容时,请使用 must-revalidate;这样在源站不可用时可以返回 504 而不是过期的备选内容。
no-store 是移除存储而不是仅要求检查;仅对确实不得存储的响应使用它。
在赋予长生命周期前先版本化不可变资产
版本化的资产 URL 包含内容指纹或发布版本,例如 app.4f2c.js。当资产字节变化时,发布不同的 URL 并更新 HTML 引用。缓存会看到新资源,因此访客在不需要对每个浏览器发出失效通知的情况下获取新资产。
对于在其新鲜期内不会变化的表示,Cache-Control: max-age=31536000, immutable 是一种实用模式。immutable 告诉支持它的客户端在资源仍“新鲜”时不要进行条件重验证。不要将它或一年期的 max-age 应用于可变且同一 URL 的文件。在被缓存的 HTML 可能仍引用它们的情况下,应保留先前的指纹化资产。
HTML 决定资源 URL,因此发布顺序必须保留被引用的生成版本。
让 HTML 通过验证保持最新,而不是长期缓存
HTML 通常有稳定的、面向人的 URL,并会随着内容、资源引用、功能开关或安全公告而变化。一种保守的公共 HTML 模式是使用 Cache-Control: no-cache,并配合 ETag 和 Last-Modified(当平台能正确生成时)。浏览器会存储主体,但在重用前发出条件请求;未改变的响应可返回 304 Not Modified 而无主体。
ETag 标识资源版本。对于过期的响应,浏览器可以在 If-None-Match 中发送该 ETag;如果匹配,服务器回复 304,否则发送新的表示。RFC 指南建议在可能的情况下在 200 响应上同时提供 ETag 和 Last-Modified。no-cache 并不保证在后退(Back)或前进(Forward)导航时一定会进行验证,因为浏览器可能恢复会话历史的快照。
ETag 必须在表示变化时改变;在不同源与部署间测试其行为。
将公共交付与个性化和敏感响应分离
共享缓存(例如 CDN)可能会为多个用户重用同一响应。不要让它在用户间重用账户特定的 HTML 或 API 数据。对于可能保存在浏览器的个性化内容,private, no-cache 是合理的起点:它阻止共享存储并要求验证。单独的 Set-Cookie 头并不能阻止缓存。
对于不应被存储的响应,请使用 no-store,并审查应用代码、CDN 规则、service worker、浏览器存储、日志和错误页。仅靠头部并不能构成隐私、合规或支付安全计划。应由合格的安全、隐私和支付审查人员评估敏感流程与适用要求。
在热缓存的浏览器和 CDN 下测试登录、登出、账户切换和权限变更。
将缓存更改作为可逆发布逐步推出
捕获未缓存与重复请求的基线头部和主体行为。在预发布环境中,先部署版本化资产,再部署引用它们的 HTML,并测试旧的已缓存 HTML 与新源站之间的兼容性。检查直接源站和 CDN 路径(如果两者都存在)。DevTools Network headers 应显示预期的策略和重复访问行为。
保留发布清单,记录资产 URL、头部规则和配置版本。如果一次发布包含不兼容的客户端文件,恢复兼容的 HTML 与应用行为,但不要覆盖已发布的指纹化文件。将 HTML 指向已知的良好生成版本,并在被缓存的 HTML 可能请求它们时同时保留两代资源。共享缓存的清除不能强制浏览器丢弃仍然“新鲜”的响应。
将头部测试失败、资产 404 与版本不匹配转化为下一次发布清单中的变更项。
