带哈希的JS/CSS/图片等静态资源可用public,max-age=31536000,immutable长期强缓存;HTML必须禁用强缓存,设no-cache,must-revalidate强制每次校验。

不能靠 max-age 单独“强制”缓存静态网页资源,关键在于组合使用 Cache-Control 指令,并匹配资源实际更新方式。单纯设 max-age=31536000 对 HTML 会出问题,但对带哈希的 JS/CSS/图片是安全且高效的。
哪些资源能用 max-age 长期缓存
只有内容实质不变、文件名自带版本标识(如哈希或时间戳)的资源才适合设置长 max-age:
-
JS/CSS 文件:例如
app.f3a7b2.js、style.e8c1d4.css -
图片/字体/图标:如
logo.9f2e1a.png、icon.woff2 - 必须配合 immutable:告诉浏览器“这个 URL 永远不会变”,跳过验证请求(If-None-Match / If-Modified-Since)
Nginx 配置写法(推荐 add_header + always)
在匹配静态资源的 location 块中添加:
location ~* \.(js|css|png|jpg|gif|woff2|svg|webp|ico)$ {
add_header Cache-Control "public, max-age=31536000, immutable" always;
# 同时建议开启 sendfile 和 open_file_cache 提升 IO 效率
}注意:always 参数确保覆盖后端(如 PHP 或代理)可能已设置的同名头,避免被意外覆盖。
为什么 HTML 不能这么配
HTML 通常是动态生成的,内容随业务逻辑实时变化。即使设了 max-age=300,浏览器也可能直接复用本地副本,跳过服务器校验,导致用户看不到新页面结构或功能。
正确做法是:
- 用
no-cache, must-revalidate:每次请求都发到服务器,由 Nginx 或后端决定是否返回 304 或新内容 - 或
private, max-age=0:禁止共享缓存,强制每次校验 - 避免
max-age=300这类中间值——它既不安全也不可控
验证是否生效
配置完务必检查响应头:
- 打开浏览器开发者工具 → Network → 刷新页面 → 点击某个 JS/CSS 文件
- 查看 Response Headers 中是否有:
Cache-Control: public, max-age=31536000, immutable - 用
curl -I https://yoursite.com/app.a1b2c3.js也能快速确认


















