引言:你的代码更新,用户为何“视而不见”?
“我明明部署了新版本,用户为什么还在看旧页面?!” —— 这是多少前端开发者深夜加班时的灵魂拷问。
问题的根源往往不是代码没上传,也不是服务器抽风,而是浏览器和服务器联手上演的一场“缓存大戏”。
本文将带你化身“侦探🕵️♂️”,用三步精准定位问题,手把手教你解决页面未更新问题,让用户永远看到最新鲜的页面!
一、案发现场:缓存是如何“偷梁换柱”的?
1.1 经典症状
•用户反馈页面功能异常,但开发者本地测试正常
•浏览器反复刷新后,index.html
引用的仍是旧版 JS/CSS 文件
•查看网络请求,某些文件状态码显示 304 Not Modified
或 200 OK (from memory cache)
1.2 幕后黑手
嫌疑人 | 作案手法 | 经典台词 |
浏览器缓存 | 擅自保留旧文件副本 | “这个 JS 我上周刚拿过!” |
Nginx 默认配置 | 未正确设置缓存响应头 | “我按规矩办事,怪我咯?” |
CDN 缓存 | 全球节点同步延迟(隐藏 Boss) | “急什么,等我喝完这杯茶” |
二、破案工具:缓存控制响应头
2.1 强缓存 vs 协商缓存
•强缓存:浏览器直接使用本地副本,不询问服务器
•协商缓存:浏览器询问服务器资源是否变化
2.2 核心原则
•HTML 文件:禁止缓存,永远从服务器获取最新版本
•静态资源(JS/CSS/图片):带 hash
文件名 + 长期缓存
•静态资源(JS/CSS/图片):非 hash
文件名 + 短期缓存
三、终极方案:三步根治缓存问题
3.1 第一步:Nginx 精准狙击(配置示例)
关键解释:
•immutable:告诉浏览器“此文件永不变”,跳过协商缓存
•no-store:对 HTML 文件下达“禁用缓存”绝杀令
•must-revalidate:资源过期时,在向原始服务器验证之前,缓存不能用该资源响应后续请求
•Pragma no-cache:禁用缓存
3.2 第二步:构建 hash 文件名(自动防旧)
使用构建工具在构建时为文件名添加 hash
:
文件内容变化 → hash 值变化 → 静态资源缓存自动失效
3.3 第三步:版本号核弹(兜底方案)
检查版本更新
1.构建时通过插件 @jd/plugin-create-version 在 HTML 中埋入版本时间、生成 version.json 2.
在调接口和切换路由时进行检查并提示刷新
index.html
version.json
checkVersion.ts(简略代码,完整版请咚咚)
四、破案验证:你的配置真的生效了吗?
4.1 一键验证工具
4.2 经典翻车现场
•症状:配置改完缓存依旧
•排查清单:
◦是否忘记 nginx -s reload?
◦所有分组都要nginx -s reload,即便使用的nginx配置集合
◦/assets/ 目录与项目hash文件静态资源目录名不一致
▪hash文件静态资源目录为 /static/ ?
▪匹配多个静态资源目录 ~* ^/(css|js|img)/
◦是否被 CDN 缓存背刺?
◦Service Worker 是否在搞鬼?
五、高级技巧:当缓存遇上跨域和接口代理
5.1 接口代理的缓存隔离
5.2 安全加固(防御 MIME 嗅探攻击)
六、总结:缓存是把双刃剑!
•用得好:提升性能,降低服务器压力
•用不好:用户看不到新功能
永远对缓存保持敬畏! 新版本部署时使用灰度发布、查看监控报警
四条黄金法则:
1.HTML 永远禁用缓存
2.带 hash
静态资源 + 长期缓存
3.不带 hash
静态资源 + 短期缓存
4.部署后第一时间验证响应头