Cache-Control: max-age=0 与 no-cache 均表示响应立即过期,强制缓存必须重新验证(max-age=0 是 SHOULD,no-cache 是 MUST),二者均会覆盖 Nginx/CDN 缓存配置,导致跳过强缓存、进入协商缓存流程。

直接看响应头里的 Cache-Control 字段,如果出现 max-age=0 或 no-cache,基本就是后端在“主动拒绝缓存”——哪怕你 Nginx 或 CDN 配了再久的缓存时间,也会被这条头一票否决。
用 curl 快速确认是否被 max-age=0 拦住
执行命令抓取原始响应头:
curl -I https://your-domain.com/static/app.js
重点检查输出中是否有:
Cache-Control: max-age=0Cache-Control: no-cacheCache-Control: private, no-store-
Pragma: no-cache(虽已过时,但部分老框架仍会发)
只要其中任意一个存在,浏览器和中间代理(包括 Nginx、CDN)都会跳过强制缓存,转为协商流程或直接回源。
对比浏览器 DevTools 的 Network 面板行为
刷新页面后,在 Network 标签页里点开某个静态资源(如 CSS/JS),查看:
-
Headers → Response Headers:确认 Cache-Control 值是否为
max-age=0 -
Size 列:若显示
200 (from memory cache)或304,说明缓存逻辑还在起作用;若全是200且 Size 明显较大,大概率每次都在回源 - 注意:不要只看
Expires字段——只要Cache-Control存在,它就完全无效
查后端代码或框架默认行为
很多框架(如 Spring Boot、Django、Express 默认中间件)会在开发环境或未显式配置时,自动给所有响应加 Cache-Control: no-cache 或 max-age=0。常见位置:
- Spring Boot:检查
WebMvcConfigurer或@ControllerAdvice中是否统一设置了响应头 - Django:查看
MIDDLEWARE是否启用了UpdateCacheMiddleware/FetchFromCacheMiddleware,或模板响应是否被never_cache()包裹 - Express:排查
res.set('Cache-Control', ...)或是否误用了res.sendStatus(200)等无头响应 - 构建工具输出的 HTML:有些脚手架(如 Vue CLI dev server)默认禁用缓存,上线前需手动覆盖
临时绕过验证:Nginx 层强制接管缓存策略
如果你确认资源本身是静态且可缓存的(比如带哈希的 JS/CSS),可在 Nginx 中屏蔽后端错误头并重设规则:
- 在对应
location块中加入:proxy_ignore_headers Cache-Control;proxy_cache_valid 200 302 1h; - 同时建议补上:
add_header X-Cache $upstream_cache_status;
方便后续用curl -I查看是否真命中 HIT - 注意:该方式仅适用于内容稳定、无用户态差异的资源;含登录态或个性化数据的接口不可盲目覆盖


















