expires modified 更稳妥——过期时间基于文件最后修改时间而非服务器时间,内容不变则缓存长期有效,更新后自动启用新周期;需确保文件系统时间戳真实可信。

对频繁变动但又不走后端逻辑的“动态静态资产”(比如由构建工具生成、带哈希但部署时可能覆盖同名路径的 JS/CSS,或 CMS 导出的 HTML 页面),直接设固定 expires 1y 有风险,而设太短又浪费性能。用 expires modified 是更稳妥的选择——它让过期时间从文件最后修改时间起算,而非当前服务器时间,配合浏览器条件请求,能真正实现“内容没变就不传”。
理解 expires modified 的核心逻辑
expires modified 1h 表示:该资源在“文件最后一次被修改的时间 + 1 小时”后过期。只要文件没改,每次请求都可能命中缓存;一旦文件更新,修改时间变化,新缓存周期立刻生效。这比固定时间缓存更贴合实际发布节奏。
注意:此方式依赖真实、可信的文件系统修改时间戳。容器中挂载只读卷、或通过内存文件系统(如 tmpfs)分发的资源,modified 可能失效,此时应改用版本号路径 + 固定长期缓存。
基础配置写法(推荐用于 /static/ 下的构建产物)
在 server 或 location 块中添加:
location ~* ^/static/.*\.(js|css|webp|png|jpg|gif)$ {
root /var/www/assets;
expires modified 1y;
add_header Cache-Control "public, immutable";
}
-
modified 1y确保只要文件不变,缓存就长期有效;一旦重新部署覆盖文件,新时间戳触发新缓存周期 -
immutable告诉浏览器:该资源在过期前绝不会变更,可跳过后续的条件请求(节省一次 HEAD 开销) - 无需额外开启
if_modified_since,Nginx 默认已启用且与expires modified协同工作
搭配 HTML 等易变内容的混合策略
HTML 文件通常不能长期缓存,但也不适合每次都全量传输。建议:
location ~* \.html$ {
expires modified 10m;
add_header Cache-Control "public, must-revalidate";
}
- 10 分钟内若文件未改,浏览器直接用缓存;超时后发起条件请求,服务端根据
Last-Modified决定返回 200 还是 304 -
must-revalidate强制浏览器过期后必须验证,避免使用陈旧副本 - 确保 HTML 文件本身具备真实、及时更新的修改时间(例如 CI 流水线中用
touch更新时间戳,或从源码生成时保留原始 mtime)
验证是否生效的关键点
用浏览器 DevTools 的 Network 面板查看响应头:
- 检查
Expires值是否为一个具体时间点,且比Last-Modified晚约你设定的时长(如Last-Modified: Wed, 18 Jun 2026 14:22:05 GMT→Expires: Thu, 19 Jun 2026 14:22:05 GMT) - 刷新页面时观察状态码:未改则应为
304 Not Modified,并显示(from memory cache)或(from disk cache) - 修改对应文件后再次请求,
Expires和Last-Modified应同步更新











