08 · Edge TTL、Browser TTL 与缓存响应头
分清浏览器、Cloudflare 边缘和源站的缓存时间,用 Cache-Control 与 CDN-Cache-Control 建立可更新的发布策略。
编辑与核验:橙宝书编辑团队 ·
完成结果
浏览器不会长期锁住可变 URL,Cloudflare 可以比浏览器保留更久的公开对象,指纹资源可以安全长缓存,私有响应明确禁止共享存储;发布时也知道该换 URL、重新验证还是精准清缓存。
详细说明
- 01浏览器
按下游 Cache-Control 与 Browser TTL 决定是否发起网络请求。
- 02Cloudflare 边缘
按 Edge TTL 与重新验证策略决定 HIT、UPDATING 或回源。
- 03源站
生成内容并返回缓存、ETag 或 Last-Modified 语义。
- 04发布系统
对不可变资源换版本 URL,对可变内容使用短 TTL 或精准刷新。
三层时间不要混用
| 层 | 主要控制 | 适合的策略 | 最难回滚的错误 |
|---|---|---|---|
| 浏览器 | Cache-Control: max-age、Browser TTL | 可变 URL 保守,指纹 URL 长缓存 | 给未版本化 HTML/JS 设置一年 |
| Cloudflare 边缘 | Edge TTL、共享缓存头、Cache Rules | 公共内容可比浏览器保留更久 | 强制覆盖私有或频繁变化响应 |
| 源站/应用 | 响应头、ETag、Last-Modified、版本 URL | 让内容语义成为单一事实源 | 不区分公开、私有与不可变内容 |
浏览器若仍认为对象新鲜,就不会向 Cloudflare 发请求。此时即使你已经 Purge Edge Cache,用户仍可能继续看到本地旧对象。因此未版本化页面和脚本不要使用难以撤回的长 Browser TTL。
响应头怎么分工
| 头或指令 | 主要消费者 | 用途 |
|---|---|---|
Cache-Control: max-age=... | 浏览器及未被专用头分开的缓存 | 定义客户端新鲜度 |
s-maxage=... | 共享缓存 | 覆盖共享缓存中的 max-age;浏览器忽略 |
Cloudflare-CDN-Cache-Control | Cloudflare | 单独定义 Cloudflare 边缘策略 |
CDN-Cache-Control | 支持该字段的 CDN | 与浏览器策略分离的通用 CDN 指令 |
| Edge TTL Cache Rule | Cloudflare | 对匹配请求覆盖边缘 TTL 响应头 |
| Browser TTL Cache Rule | 下游响应 | 覆盖发给浏览器的 Cache-Control 行为 |
不要把 s-maxage 与 stale-while-revalidate 随意组合
当前 Cloudflare 行为中,s-maxage 隐含 proxy-revalidate,会阻止共享缓存直接提供 stale 内容。若需要不同的边缘 TTL,同时保留异步 stale-while-revalidate,官方建议使用源站 max-age + stale-while-revalidate,再由 Cache Rule 的 Edge TTL 单独设置 Cloudflare 新鲜度。
三个可审查模板
指纹静态资源
Cache-Control: public, max-age=31536000, immutable只用于 URL 中包含内容哈希、每次内容变化都会换 URL 的 JS、CSS、字体和图片。不要把它复制到 /app.js 或 /latest.pdf 这类可变 URL。
可更新的公开 HTML 或 API
Cache-Control: public, max-age=60
Cloudflare-CDN-Cache-Control: public, max-age=300, stale-while-revalidate=30
ETag: "content-version-42"浏览器一分钟后重新询问,Cloudflare 可保留五分钟,并在允许窗口内异步更新。示例数字只是保守起点,必须按内容更新频率、错误成本和回源能力调整。
私有页面或任务结果
Cache-Control: private, no-store适用于账号、账单、管理、私有图片/PDF 转换结果和带用户权限的数据。不要依靠超短 TTL 把私有共享缓存变安全。
在 Cache Rules 中选择 Edge TTL 模式
| 模式 | 行为 | 适用情况 |
|---|---|---|
| 有头则遵循,无头绕过 | 响应没有缓存头时不存储 | 应用有明确内容治理,安全优先 |
| 有头则遵循,无头用 Cloudflare 默认 | 保留默认静态扩展名行为 | 常规静态站点迁移 |
| 忽略源站头并使用规则 TTL | 强制使用指定时间 | 仅限范围窄、已证明公开的对象 |
最后一种会越过源站关于新鲜度甚至隐私的表达。若使用,规则必须排除 Set-Cookie、身份路径和私有 API,并通过两个账号测试。
验证 TTL 与重新验证
curl -sS -D first.headers -o /dev/null https://www.example.com/assets/app.abc123.js
curl -sS -D second.headers -o /dev/null https://www.example.com/assets/app.abc123.js检查 Cache-Control、Cloudflare-CDN-Cache-Control、Age、CF-Cache-Status、ETag 与 Last-Modified。Age 在命中时增长,在重新验证、清除或驱逐后重置。存在 stale-while-revalidate 时,过期后的请求可能看到 UPDATING,这是异步更新的预期状态。
下一篇将这些规则应用到 CMS、SaaS 与 AI 制作的应用。
官方来源
这篇内容帮你完成目标了吗?
内测反馈只在当前浏览器生成,不会自动上传。