Cache-Control优先级高于Expires,因HTTP/1.1规范明确其为权威机制,Expires仅为兼容性补充;Nginx中expires指令自动生成Cache-Control,add_header需加always才可覆盖。

在 Nginx 中,Cache-Control 的优先级高于 Expires。当两个响应头同时存在时,浏览器会忽略 Expires,只遵循 Cache-Control 的指令。
为什么 Cache-Control 优先级更高
HTTP/1.1 规范(RFC 7234)明确规定:Cache-Control 是权威缓存控制机制,而 Expires 是 HTTP/1.0 遗留字段,仅作为兼容性补充。现代浏览器均以 Cache-Control 为准,即使 Expires 设置得更宽松或更严格,也不会影响实际缓存行为。
Nginx 中如何设置才有效
在 Nginx 配置中,需注意指令执行顺序和覆盖关系:
-
expires指令会同时设置Expires和Cache-Control: max-age=...,是快捷方式,但本质仍生成Cache-Control - 若手动用
add_header Cache-Control ...,它默认不会覆盖expires自动生成的Cache-Control,因为add_header在输出阶段较晚,且 Nginx 对重复 header 默认保留最后一个 —— 实际结果取决于配置位置和是否启用always - 推荐统一使用
expires指令管理静态资源缓存;如需精细控制(如 no-cache、immutable、s-maxage),再配合add_header Cache-Control ... always
常见误配与排查建议
以下情况容易引发预期外的缓存行为:
- 同时写
expires 1h;和add_header Cache-Control "public, max-age=300";:后者可能被忽略,除非加上always - 在
location块中用add_header覆盖上级expires,但未加always→ 缓存头不生效(尤其对 304/200 响应) - 反向代理场景下,后端应用已返回
Cache-Control,Nginx 又用expires覆盖 → 实际以 Nginx 最终发出的为准,可用curl -I验证响应头
快速验证方法
部署后立即检查真实响应头:
- 终端执行:
curl -I https://your-site.com/static/logo.png - 关注输出中是否同时存在
Cache-Control和Expires,并确认max-age值是否符合预期 - 用 Chrome DevTools > Network > Header 查看 “Response Headers”,比对各资源的实际缓存策略










