要确保静态资源不被浏览器缓存,需组合禁用强缓存+强制校验+阻止存储:设cache-control为"no-store, no-cache, must-revalidate, max-age=0",pragma为"no-cache",expires为"0",并精准匹配资源路径避免误伤。

要确保静态资源不被浏览器缓存、每次请求都拉取最新版本,用 expires off 是不够的——它只是不添加 Expires 和 Cache-Control: max-age 头,但浏览器仍可能按默认策略或历史行为缓存。真正实现“实时更新、不被缓存”,需要组合禁用强缓存 + 强制校验 + 阻止存储。
明确禁用所有缓存机制
expires off 本身不发送任何缓存头,属于“不表态”,而你需要的是“明确拒绝”。应配合 add_header Cache-Control 设置完整指令:
-
no-store:禁止浏览器和中间代理存储任何副本(最严格) -
no-cache:允许缓存,但每次使用前必须向服务器验证(走 304 协商) -
must-revalidate:强制遵守过期时间,过期后不可擅自使用 -
max-age=0:声明缓存立即过期,触发验证流程
推荐写法(例如针对 HTML 或调试用资源):
location ~* \.html$ {
expires off;
add_header Cache-Control "no-store, no-cache, must-revalidate, max-age=0";
add_header Pragma "no-cache";
add_header Expires "0";
}
匹配目标资源路径要精准
避免误伤其他静态文件。比如只让入口 HTML 实时更新,就不要写 location /,而应:
- 精确匹配:
location = /index.html - 正则匹配:
location ~* ^/(index|main|app)\.html$ - 排除带哈希的资源:
location ~* \.(js|css|png)$不应包含在该规则内
否则会导致 CSS/JS 也被禁用缓存,影响性能且无必要。
注意 add_header 的覆盖行为
同一个 location 块中多次 add_header,后出现的会覆盖前面的。建议把所有缓存控制头写在一行,或集中管理:
add_header Cache-Control "no-store, no-cache, must-revalidate, max-age=0"; add_header Pragma "no-cache"; add_header Expires "0";
若同时存在其他 add_header(如 CORS 或安全头),确保缓存头不被意外覆盖。
验证是否真正生效
配置重载后,用 curl -I 或浏览器 Network 面板检查响应头:
- 没有
Expires字段(或值为0) -
Cache-Control包含no-store或至少含no-cache, max-age=0 - 刷新页面时,状态码是
200(非缓存)或304(有协商但内容未变),而非200 from disk cache或from memory cache
特别注意:如果看到 200 from memory cache,说明浏览器仍在复用本地副本——那一定是缓存头没生效或被其他规则覆盖了。











