高效缓存静态资源关键在于合理配置Cache-Control头,而非仅用expires;需按资源类型区分设置public、max-age、immutable等指令,并通过add_header在Nginx中精准控制。

要让 Nginx 高效缓存静态资源,关键不是简单加个 expires,而是用好 Cache-Control 头——它比过期时间更灵活、更符合现代浏览器和 CDN 的协作逻辑。
理解 Cache-Control 的核心指令
Cache-Control 是 HTTP/1.1 定义的响应头,由多个逗号分隔的指令组成,服务器通过它精确控制资源在客户端、代理、CDN 等各环节的缓存行为。常用且实用的指令包括:
- public:允许任何中间节点(如 CDN、代理)缓存该响应;适合公开的 JS/CSS/图片等资源
- private:仅允许用户浏览器缓存,禁止共享缓存(如 CDN)存储;适合含用户信息的 HTML 片段(不推荐用于纯静态资源)
-
no-cache:强制每次请求都向源站验证(发送条件请求,如带
If-None-Match),但允许复用已缓存内容(304 响应);适合内容可能更新但无需实时生效的资源 - no-store:完全禁止缓存,所有环节都必须重新获取;适用于敏感数据(如登录态页面),一般静态资源不用
- max-age=<seconds>:定义资源“新鲜期”,单位秒;浏览器在该时间内直接使用本地副本,不发请求;是静态资源缓存最常用的指令
-
must-revalidate:过期后必须向源站验证,不可擅自返回过期资源;增强缓存一致性,建议与
max-age搭配使用
Nginx 中配置 Cache-Control 的三种方式
Nginx 不直接生成 Cache-Control 头,需通过 add_header 或 expires 指令间接或直接控制。推荐优先用 add_header,更清晰可控:
-
方式一:add_header(推荐)
在location块中显式设置,注意它不会覆盖已有同名头(除非开启always参数):add_header Cache-Control "public, max-age=31536000, must-revalidate"; -
方式二:expires 指令(兼容旧配置)
expires 1y;会自动设置Expires头和Cache-Control: max-age=31536000;但它无法添加public或must-revalidate等额外指令 -
方式三:add_header + always(强制覆盖)
当上游(如 FastCGI/Proxy)已设 Cache-Control,需覆盖时使用:add_header Cache-Control "public, max-age=86400" always;
按资源类型精细化配置示例
不同静态资源更新频率差异大,应区别对待。以下为生产环境常用配置片段(放在 server 或 location 块内):
-
长期不变资源(带哈希指纹的 JS/CSS/字体)
location ~* \.(js|css|woff2|ttf|eot)$ {<br> add_header Cache-Control "public, max-age=31536000, immutable";<br>}
注:immutable是较新指令(Chrome 49+ 支持),告知浏览器该资源在max-age内绝不会变,可跳过后续验证请求 -
常规图片(PNG/JPG/GIF)
location ~* \.(png|jpe?g|gif|webp)$ {<br> add_header Cache-Control "public, max-age=604800"; # 7天<br>} -
HTML 文件(通常不缓存或短缓存)
location = /index.html {<br> add_header Cache-Control "no-cache, must-revalidate";<br>}
避免因 HTML 缓存导致新版本 JS/CSS 路径未更新而白屏 -
图标与 manifest(如 favicon.ico、manifest.json)
location ~* \.(ico|svg|json)$ {<br> add_header Cache-Control "public, max-age=86400";<br>}
验证与调试技巧
配置生效后,务必通过真实请求验证响应头是否正确:
- 用
curl -I https://yoursite.com/app.js查看返回的Cache-Control和Expires头 - 在 Chrome DevTools 的 Network 标签页中,检查资源的 Size 列:显示 from disk cache 或 from memory cache 表示命中缓存;200 OK (from cache) 表示使用了
no-cache验证机制 - 注意:Nginx 的
add_header在 304 响应中默认不生效(因为 304 不走完整响应流程),若需对 304 也加头,必须加always参数 - 若使用 CDN(如 Cloudflare),确认其未覆盖或修改源站的
Cache-Control;可在 CDN 后台设置“尊重源站缓存头”


















