跳到内容

⚡ 缓存头分析器

分析 Cache-Control、ETag、Expires、Vary、Age — max-age / s-maxage 转为可读格式。自动检测主流 CDN。

完全免费 无需注册 服务器处理 无日志 / 数据库 限速 5 种语言 深色模式

⚠️ 请求从 DevLab 服务器发起。不允许私有 IP 地址和 localhost。

📚 Cache-Control 参考

public: 任何缓存(包括 CDN)可缓存

private: 仅浏览器(不允许共享缓存)

no-store: 完全不缓存

no-cache: 可以缓存但每次必须重新验证

max-age=N: N 秒内有效

s-maxage=N: 仅适用于共享缓存的 max-age

immutable: 无需重新验证(即使重新加载) — 适合带哈希的资源

stale-while-revalidate=N: 过期后 N 秒内仍返回旧值,后台重新验证

stale-if-error=N: 源站错误时 N 秒内返回旧值

📖 本诊断能告诉你什么

本诊断从指定 URL 的响应标头中取出 Cache-ControlETagLast-ModifiedExpires 以及 CDN 专有标头,并拆解其中的指令。它只能判断「你下达了什么指令」,无法得知实际是否被缓存。浏览器在存储紧张时会不顾指令直接丢弃,CDN 也可能用自家规则覆盖。

检查项 含义 未通过时的处理
完全没有写 Cache-Control 不写并不等于「不缓存」,而是缓存方可以自行推测有效期(启发式缓存)。若存在 Last-Modified,常见实现会把距最后更新时间的约 10% 视为新鲜期。也就是说,一年前更新的页面可能被缓存约一个月。 请在所有响应中显式声明。三种模式基本够用:HTML 用 no-cache(会存储,但每次都回服务器校验)、带内容哈希的静态资源用 max-age=31536000, immutable含个人信息的响应用 private, no-store。两者名字容易混淆:no-cache 会存储,no-store 不存储。
给可变文件设置了很长的 max-age style.css 这类固定文件名设置一年的 max-age即使更新,老访客一年内也看不到。更糟的是,已经分发到浏览器的缓存无法从服务器端撤销——CDN 的清除只能到达边缘节点,触及不到用户设备。 长 TTL 只应与「更新时文件名随之改变」的设计配套使用——把内容哈希放进文件名,如 app.4f2c1a.css,并改写 HTML 中的引用。这样加 immutable 才安全,刷新时连重新校验都不会发生。若长 TTL 已经分发出去,改文件名并放弃旧文件是唯一的补救办法。
给个性化响应加了 public 若包含登录名或购物车内容的页面带上 public(或 s-maxage),共享缓存就会保存它,并原样发给下一位不同的访客。让一个用户看到另一个人的个人信息,是缓存配置可能造成的最严重事故,且常在引入 CDN 之后立刻暴露。 认证后的响应请返回 Cache-Control: private, no-storeVary: Cookie 理论上也能隔离,但会按 Cookie 值产生不同条目,实际上等于缓存失效,作为 CDN 减负手段是失败的。更可靠的设计是按路径或子域分离匿名流量与已登录流量,只让前者可缓存。

缓存的可怕之处在于,错误一旦脱手就会持续存在。改了配置也无法撤回已经分发出去的指令,因此铁律是拿不准就先设短、之后再延长。配合 stale-while-revalidate,可以在过期瞬间不让用户等待,先返回旧内容再于后台更新,因此即使 max-age 较短也不会牺牲体感速度。若使用 CDN,把 max-age(面向浏览器)设短、s-maxage(面向 CDN)设长并靠清除即时生效,是最好管理的组合。

🔗 相关工具