应按资源类型在 location 块中用 expires 设相对缓存时长,并必须配合 add_header Cache-Control;哈希静态资源设 expires 1y + public, immutable;HTML 设 expires -1s + no-cache;图片、字体等依更新频率分级设置,禁止单独依赖绝对时间。

直接用 expires 指令控制浏览器缓存,核心是“按资源类型设时长 + 必须配合 Cache-Control + 避免单独依赖绝对时间”。它不是简单写个 expires 1y 就完事,而是要贴合资源更新规律和浏览器实际行为。
必须放在 location 块里,按后缀精准匹配
不能写在 http 或 server 全局块中——那样会误伤 HTML、API 等不该强缓存的内容。推荐用大小写不敏感正则匹配:
-
location ~* \.(js|css|woff2?|ttf|eot|svg)$ { expires 1y; }(哈希化静态资源) -
location ~* \.(jpg|png|webp|gif)$ { expires 30d; }(普通图片) -
location ~* \.html$ { expires -1s; }(HTML 禁用强缓存) -
location = /favicon.ico { expires 1M; }(图标类低频资源)
时间值选相对而非绝对,优先用语义化单位
expires 支持 1h、7d、1y、max(等价于 2037 年末)、-1s(立即过期)等,不建议用 @15h 这类绝对时间点——它只适合极少数定时发布场景,且对移动端设备时钟偏差敏感。
常见合理取值:
- 带哈希的 JS/CSS:用
expires 1y - 用户上传头像/动态图:用
expires -1s或expires 0 - 字体、SVG 图标:用
expires 1y安全且高效 - 未版本化的 CSS/JS:最多设
expires 1h,防止更新失效
一定要搭配 add_header Cache-Control 使用
expires 自动写入 Expires 和基础 Cache-Control: max-age=xxx,但现代浏览器更信任 Cache-Control,且它基于请求时间计算,不受客户端时钟影响。所以必须手动补全:
- 对哈希文件:
add_header Cache-Control "public, immutable, max-age=31536000"; - 对 HTML:
add_header Cache-Control "no-cache, must-revalidate"; - 对需禁止代理缓存的资源:
add_header Cache-Control "private, no-store";
注意:add_header 在同一作用域多次出现会覆盖前值,建议集中写、避免分散。
验证是否真正生效,别只看配置
改完配置后执行 sudo nginx -t && sudo systemctl reload nginx,然后打开浏览器开发者工具 Network 面板检查:
- 找一个 JS 或图片,确认响应头含
Cache-Control且max-age值符合预期 - 查看
Expires时间是否为 GMT 格式、是否在将来 - 刷新页面,状态码显示
304 Not Modified或200 (from memory cache)才算成功 - 特别留意 iOS Safari:对
index.html类入口页,禁用缓存比设短时间更稳妥


















