
网站已经发布了新图片、新 CSS 或新页面,访问域名时却一直看到旧内容,这类问题经常被笼统地归为“CDN 缓存没有刷新”。实际排查时,旧内容可能来自浏览器、本地代理、CDN 边缘节点,也可能是源站本身没有更新。直接清空全部缓存虽然偶尔有效,却会掩盖配置问题,还可能让大量请求同时回源。
本文给出一套适用于常见 CDN 平台的排查顺序。你可以先确认旧内容停在哪一层,再检查缓存键和缓存规则,最后执行影响范围尽可能小的刷新操作。
适用范围:使用 CDN 加速静态资源、下载文件、WordPress 页面或前后端分离网站的场景。不同厂商的响应头和控制台名称有所差异,实际结果以当前平台文档与控制台为准。
一、先确认源站内容是否已经更新
CDN 只负责分发源站返回的内容。源站文件没有替换成功、应用发布到了错误目录,或者上游反向代理仍在缓存时,刷新 CDN 也不会得到新版本。
先查看通过 CDN 域名返回的响应头:
curl -I https://www.example.com/assets/app.css
重点记录以下信息:
| 响应信息 | 用途 |
|---|---|
Cache-Control |
判断响应是否允许缓存以及缓存时间 |
Age |
判断对象在共享缓存中已经停留了多长时间;部分平台不会返回 |
ETag、Last-Modified |
判断新旧版本以及是否发生条件请求 |
CF-Cache-Status、X-Cache 等 |
查看厂商提供的命中、未命中或回源状态 |
Via、厂商请求 ID |
辅助确认请求经过了哪些代理或节点 |
如果知道源站 IP,可以使用 --resolve 绕过 CDN,同时保持正确的域名和 HTTPS SNI:
curl -I --resolve www.example.com:443:203.0.113.10 \
https://www.example.com/assets/app.css
将其中的示例 IP 换成自己的源站地址,然后对比源站与 CDN 返回的 ETag、Last-Modified、Content-Length 或文件哈希。
- 源站仍是旧内容:检查部署目录、对象存储版本、Nginx 缓存、应用缓存和发布流程。
- 源站是新内容,CDN 是旧内容:继续检查缓存键、节点缓存和刷新任务。
- 源站与 CDN 都是新内容,浏览器仍显示旧页面:优先检查浏览器缓存、Service Worker 和页面引用的资源 URL。
二、排除浏览器缓存和 Service Worker
浏览器缓存与 CDN 缓存是两套独立机制。CDN 已经回源并缓存了新文件,浏览器仍可能按照旧响应中的 max-age 继续使用本地副本。
建议按下面的方式验证:
- 使用无痕窗口访问,不要只按普通刷新。
- 在开发者工具的 Network 面板中勾选“Disable cache”后重新加载。
- 查看请求是来自网络、memory cache、disk cache,还是 Service Worker。
- 如果网站使用 PWA,检查 Service Worker 的缓存名称、更新策略和激活状态。
静态资源发布时最好使用带内容哈希的文件名,例如:
app.7f3a9c2.css
main.a81d09e.js
文件内容变化时 URL 也随之变化,可以绕开旧缓存。仅在原 URL 后随手添加查询参数并不总是有效,因为 CDN 可能被配置为忽略查询字符串。
三、检查缓存键是否把不同请求当成同一个对象
缓存键决定 CDN 用哪些请求信息区分缓存对象。常见组成包括域名、路径、查询字符串,以及经过配置后加入的请求头或 Cookie。
下面几种配置容易造成“刷新了却没变化”:
- CDN 忽略全部查询字符串,
app.css?v=2与app.css?v=3命中同一缓存对象。 - 源站根据
Accept-Encoding、语言或设备类型返回不同内容,但这些维度没有进入缓存键。 - 页面根据 Cookie 展示不同状态,CDN 却缓存了其中一个版本并共享给其他请求。
- 同一资源存在大小写不同、尾部斜杠不同或 URL 编码不同的地址,刷新任务只覆盖了其中一种形式。
检查控制台中的“缓存键”“查询参数缓存”“忽略参数”“Cookie 缓存”“请求头缓存”等配置。缓存键不是越复杂越好:维度过少会串内容,维度过多则会降低命中率。只加入确实改变响应内容的参数、请求头和 Cookie。
如果要判断查询参数是否参与缓存,可以连续请求两个只改变参数的 URL,并比较厂商缓存状态、Age 和响应内容:
curl -I https://www.example.com/assets/app.css?v=test-a
curl -I https://www.example.com/assets/app.css?v=test-b
这项测试只能说明当前规则下两个请求是否可能共用缓存,不能代替控制台配置检查。
四、检查源站响应头和 CDN 缓存规则
缓存时间可能同时受源站响应头和 CDN 控制台规则影响。常见情况包括:
- 源站返回较长的
Cache-Control: max-age=...,浏览器继续使用旧文件。 - 源站设置了
s-maxage,共享缓存按该值保存,行为与浏览器缓存时间不同。 - CDN 控制台设置了“强制缓存”或“忽略源站”,覆盖了源站响应头。
- 多条规则同时匹配,优先级更高的规则给资源设置了更长 TTL。
- HTML、接口响应与静态资源共用一套规则,导致本应短缓存或不缓存的内容被长期保存。
可以按内容类型拆分策略:
| 内容类型 | 常见处理思路 |
|---|---|
| 带哈希的 CSS、JS、字体、图片 | 可以设置较长缓存时间,内容变化时更换 URL |
| HTML 页面 | 使用较短 TTL,或结合条件请求进行更新验证 |
| 登录页、购物车、用户中心 | 通常不应作为公共内容缓存,需结合认证状态和 Cookie 规则 |
| API 响应 | 按接口用途单独评估,避免把用户相关响应共享缓存 |
no-cache 并不等于完全禁止保存,它通常要求缓存复用前进行验证;no-store 才表示不应存储响应。配置时要同时看浏览器、CDN 与源站的实际行为,不要只凭字段名称判断。
五、刷新缓存时先缩小影响范围
确认 CDN 节点仍保存旧对象后,优先刷新具体 URL,再考虑目录、标签或全站清理。刷新范围越大,短时间内回源请求越多,源站带宽和应用负载也越容易突然升高。
推荐顺序如下:
- 列出确实发生变化的完整 URL,包括协议、域名、路径和参数形式。
- 先刷新单个文件或小批量 URL。
- 等待任务状态变为完成,不要把“已提交”当成“所有节点已经生效”。
- 从不同网络或平台提供的节点诊断工具再次请求。
- 只有无法确定旧对象范围时,才评估目录或全站刷新。
刷新与预热解决的问题不同:
- 刷新用于删除或标记旧缓存失效,让下一次请求回源获取新内容。
- 预热用于提前把指定内容拉到节点,减少首次访问回源带来的延迟。
常见发布顺序是先完成源站更新,再刷新旧 URL;对大文件或访问量高的静态资源,可在刷新后按平台能力执行预热。不要在源站尚未更新时预热,否则可能把旧内容再次拉入缓存。
六、刷新完成后怎样确认已经生效
一次命中或未命中不足以说明所有节点都已更新。CDN 是分布式系统,不同地区、不同运营商和不同缓存层可能存在短暂差异。
可以做以下核对:
curl -sS -D - -o /dev/null https://www.example.com/assets/app.css
检查响应头中的缓存状态、Age、ETag 和更新时间。随后再次请求同一 URL,观察第一次回源后是否正常命中。对于可下载文件,还可以比较哈希:
curl -sS https://www.example.com/assets/app.css | sha256sum
Windows PowerShell 可先下载到临时文件,再使用:
Get-FileHash .\app.css -Algorithm SHA256
如果只有部分地区仍返回旧内容,记录以下信息后再提交给 CDN 厂商排查:
- 发生时间和时区
- 完整 URL
- 客户端地区与运营商
- 响应头和厂商请求 ID
- 期望版本与实际版本的哈希或
ETag - 已执行的刷新任务 ID 及完成时间
这些信息比“缓存没刷新”更容易定位到具体节点或配置链路。
七、常见无效操作与对应原因
1. 反复清理浏览器,但 CDN 节点仍是旧内容
浏览器清理只能移除本地副本。先用 curl -I 查看 CDN 响应,再决定处理哪一层缓存。
2. 添加随机参数后仍然看到旧文件
CDN 可能忽略查询字符串,或者只保留白名单参数。需要检查缓存键规则,不能把随机参数当成通用解决方案。
3. 刷新任务显示完成,页面仍没变化
页面可能引用了另一个域名、另一个路径或经过构建工具重命名后的文件;也可能是 Service Worker 在返回本地缓存。通过开发者工具确认浏览器实际请求的 URL。
4. 全站刷新后短暂出现 5xx 或源站变慢
大量缓存同时失效会提高回源量。应先确认源站容量,分批刷新重要 URL,并对高访问资源安排预热。
八、如何减少以后再次出现旧缓存
- 静态资源文件名加入内容哈希,版本变化时生成新 URL。
- HTML、接口和静态资源分别设置缓存策略。
- 把 CDN 刷新任务加入发布流程,并检查任务是否完成。
- 发布后自动校验关键 URL 的状态码、
ETag、文件哈希和缓存状态。 - 记录缓存规则变更,尤其是查询参数、Cookie、请求头和规则优先级。
- 为源站保留容量余量,避免刷新或缓存穿透时出现回源过载。
遇到 CDN 缓存不更新时,排查顺序可以固定为:确认源站版本,排除浏览器和 Service Worker,检查缓存键与 TTL,再做定向刷新和跨节点验证。按缓存层逐步缩小范围,通常比直接清空全站缓存更快,也更容易找到配置问题。
参考资料
- Cloudflare Docs:Cache keys
https://developers.cloudflare.com/cache/how-to/cache-keys/
- Cloudflare Docs:Cloudflare cache responses
https://developers.cloudflare.com/cache/concepts/cache-responses/
- Cloudflare Docs:Purge cache
https://developers.cloudflare.com/cache/how-to/purge-cache/
- AWS CloudFront Developer Guide:Understand the cache key
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/understanding-the-cache-key.html
- AWS CloudFront Developer Guide:Invalidating files
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html
- MDN Web Docs:HTTP caching
https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Caching
资料核验日期:2026年9月1日




