expires modified 可基于文件最后修改时间生成缓存头,避免旧缓存未过期但内容已更新的问题;需置于 location 块中且仅对本地文件生效,配合 if_modified_since before 可提升协商缓存效率。

直接用 expires modified 就能实现基于文件最后修改时间的缓存控制,无需额外脚本或 map 文件,特别适合静态资源路径明确、内容会更新但不频繁变动的场景(比如 /static/js/ 或 /assets/css/)。
expires modified 的核心作用
它让 Nginx 不再以“当前时间 + 固定时长”计算过期时间,而是以“文件最后修改时间 + 指定时长”生成 Expires 和 Cache-Control: max-age=… 响应头。这样,同一份资源只要没改,每次请求的缓存有效期都从它上次被改动的时间起算,天然避免了“旧缓存未过期但内容已更新”的问题。
例如:一个 JS 文件在 2026-06-15 10:00 被部署,配置 expires modified 1y;,那么它的 Expires 头就是 Mon, 15 Jun 2027 10:00:00 GMT;若 6 月 18 日又更新了一次,下次请求就会自动变成 Thu, 18 Jun 2027 14:22:00 GMT。
正确写法与位置要求
该指令必须放在 location 块中,且只对实际磁盘文件生效(即使用 root 或 alias 指向真实路径)。Nginx 会通过系统调用获取文件的 mtime,因此反向代理或动态 upstream 不支持此参数。
location /static/ { root /var/www/site; expires modified 365d; }location ~ \.(js|css|png|jpg)$ { alias /opt/assets/; expires modified 90d; }- 错误示例:
location /api { proxy_pass http://backend; expires modified 1h; }—— 不起作用,因为不是本地文件
配合 if_modified_since 提升协商缓存效率
仅靠 expires modified 是强制缓存策略,用户刷新或硬刷新仍可能绕过。建议搭配 if_modified_since before;,让浏览器在缓存过期后发起带 If-Modified-Since 的请求时,Nginx 可接受“等于或早于”的时间匹配,更宽松地返回 304。
完整示例:
location /static/ {
root /var/www/site;
expires modified 365d;
if_modified_since before;
add_header Last-Modified "";
}
注意:Last-Modified 由 Nginx 自动添加,无需手动设置;add_header Last-Modified "" 是可选的清理操作,防止上游或模块意外覆盖。
和 map + $expires_time 方案的区别
expires modified 是轻量级内置方案,零运维成本,适用于大多数常规静态服务;而 map + 外部脚本方式适合 CI/CD 场景,比如需要把版本哈希嵌入 URL、或想为不同构建产物设定差异化过期策略(如 vendor.js 缓存 1 年,app.[hash].js 缓存 1 小时)。两者不互斥,但日常运维优先选 modified。











