页面改了、样式表换了,访客打开却还是旧样子;图片明明替换过,前台显示的仍是上一版。这类问题很少是代码写错了,多半是缓存和资源版本没安排好。缓存本来是为了让站点更快,设置得不合适,就变成“改了没人看到”。下面这份自查围绕缓存头、资源命名和更新后的清理动作展开,适合每次前端资源上线后过一遍。
先分清站点上有几层缓存
排查之前,最好把链路上可能缓存的地方列出来,否则很容易只清了一层,另一层还在发旧文件。
- 浏览器缓存:访客本地保存的副本,由响应头里的 Cache-Control、Expires、ETag 等字段决定存多久。
- CDN 或反向代理缓存:位于服务器前面的节点,通常按 URL 缓存整份响应,需要主动清理或等它自然过期。
- 服务端缓存:页面片段缓存、对象缓存、模板编译缓存等,属于应用层面的机制。
- 本地开发缓存:自己电脑上的浏览器缓存,调试时最容易误判,先确认是不是只影响你一个人。
一个简单的判断方法:无痕窗口打开是否正常、换一台设备是否正常、带随机参数访问是否正常。三种结果组合起来,基本能定位问题在哪一层。
缓存头怎么写才不容易出错
核心思路是按文件类型区分,而不是给整站套一个统一的时长。
静态资源适合长缓存
CSS、JS、字体、图标这类内容不常变,且变了一定会改文件名的资源,可以设置较长的 max-age,并配合 immutable,让浏览器在有效期内直接使用本地副本,不再发请求确认。
HTML 与接口数据适合短缓存
页面文档本身承载着最新的内容结构,如果给它设了很长的缓存,更新就传导不出去。通常做法是短缓存加协商缓存,让浏览器带着 ETag 或 Last-Modified 询问一次,服务端返回 304 即可,既省流量又不至于发旧内容。
别把不该缓存的地址缓存住
登录态页面、购物车、后台入口、带用户身份的接口,都应该明确标记为私有或不缓存,避免在共享节点上被其他访客读到。
给资源加版本标识
让浏览器“知道文件变了”,靠的是地址变化,而不是反复清缓存。常见的几种做法:
- 文件名哈希:app.8f3c1a.css 这类命名,内容一变文件名就变,最稳妥,也方便 CDN 分层缓存。
- 查询参数:app.css?v=20240612,改动成本低,但部分缓存节点对查询串的处理不一致,需要确认 CDN 的缓存键是否包含参数。
- 目录版本:把整批资源放进带版本号的目录,适合整体发布,但要注意旧目录的清理,别让磁盘一直堆着历史文件。
无论用哪种方式,都要保证 HTML 中引用的地址和实际发布的文件名一致,改完顺手全局搜一遍旧地址有没有残留。
更新之后怎么让旧缓存失效
- 确认新文件已经部署到所有节点,而不是只传了一台机器。
- 如果资源换了文件名,HTML 引用已经指向新地址,通常不需要额外操作。
- 如果沿用旧地址,就需要在 CDN 控制台提交刷新,或等待缓存自然过期。
- 服务端缓存按业务逻辑清理,模式缓存、页面缓存、对象缓存分头确认。
- 用无痕窗口和外部网络各访问一次,核对返回的响应头是否符合预期。
缓存的目标不是让内容一直不变,而是让不变的东西安心缓存,让会变的东西及时更新。
一份可以照着走的自查清单
- 静态资源是否都带版本标识,且版本随内容变化。
- HTML 文档的缓存时长是否足够短,不会挡住内容更新。
- 登录态与个性化页面是否已明确禁止公共缓存。
- CDN 的缓存键设置是否和实际需求一致,有没有漏掉关键参数。
- 每次发布是否有固定的刷新步骤,而不是出了问题再手动清。
- 缓存相关的问题是否记录到运维文档里,方便下次快速定位。
把这几项固定成发布流程的一部分,改版和日常更新都会省心不少:访客拿到的是新版,服务器也不必为同一份文件反复应答。