强刷浏览器仍回源,说明未进入缓存流程,而是用户主动跳过强缓存;需排查devtools禁用缓存、响应头是否生效及html缓存陷阱。

强刷浏览器(如 Ctrl+F5 或 Cmd+Shift+R)仍回源,说明缓存策略未生效或被主动绕过,不是“有效期没到”的问题,而是“根本没进缓存流程”。关键要区分:强刷不是在用缓存,而是在刻意跳过缓存。
强刷行为本身就会禁用强缓存
浏览器对强刷有明确定义:带上 Cache-Control: no-cache 或 Pragma: no-cache 请求头,强制要求服务器重新验证资源。此时即使 max-age=3600 且未过期,浏览器也不会走 200 (from disk cache),而是发请求,服务器返回 304 或 200(新内容)。这不是缓存失效,是用户主动放弃强缓存。
- Network 面板里能看到该请求的 Request Headers 含 no-cache
- 状态码若是 304,说明协商缓存生效了;若是 200(非 from cache),说明服务端返回了新资源
- 这种行为和“缓存有效期”无关,属于人为触发的验证流程
检查是否误启用了开发者工具的禁用缓存
DevTools 的 Network 面板若勾选了 Disable cache,所有请求都会跳过本地磁盘/内存缓存,哪怕页面是正常打开(非强刷)也会回源。这个设置极容易被忽略,尤其在调试时开启后忘记关闭。
- 每次排查前先确认该选项是否已取消勾选
- 无痕窗口可快速验证:它默认不启用任何开发者工具设置,也不继承普通窗口的缓存状态
- 如果无痕窗口能正常命中缓存(显示 200 from disk cache),基本锁定是本窗口配置干扰
确认响应头是否真正生效且未被覆盖
即使配置了 expires 或 Cache-Control,也可能因 Nginx location 匹配错误、代理透传、或后端响应头冲突而未实际下发。
- 用 curl -I 直接请求资源 URL,看响应中是否有 Cache-Control 或 Expires 字段,且状态码为 200(非 4xx/5xx)
- 特别注意 proxy_pass 场景:若后端返回了 Cache-Control: no-store 或 Set-Cookie,Nginx 默认不会覆盖,导致强缓存被禁用
- 检查是否在更外层 location 或 server 块中写了 add_header 指令,无意中覆盖了原本的缓存头
留意 HTML 文件的缓存陷阱
很多项目 JS/CSS 缓存配置正确,但 index.html 被长期缓存,导致用户始终加载旧 HTML,里面引用的仍是旧文件路径(如 app.a1b2c3.js),而该旧路径可能已被 CDN 或 Nginx 删除或重定向,最终回源失败或返回 404。
- HTML 应设为不缓存:Cache-Control: no-cache, must-revalidate 或 max-age=0
- 确保构建产物中 JS/CSS 文件名含 content hash(如 main.8a2f1e.js),这样 HTML 更新后会引用新路径,天然规避旧缓存干扰
- 若 HTML 走了强缓存,用户看不到新 JS,也就无法触发新资源的缓存逻辑











