
在单页应用中,index.html 必须禁止浏览器缓存,否则用户可能因加载旧版 HTML 而引用过期的 JS/CSS 资源;仅依赖 expires 指令配合 map 判断 Content-Type 不可靠,应改用更精准、语义明确的 Cache-Control 头。
在单页应用中,`index.html` 必须禁止浏览器缓存,否则用户可能因加载旧版 html 而引用过期的 js/css 资源;仅依赖 `expires` 指令配合 `map` 判断 `content-type` 不可靠,应改用更精准、语义明确的 `cache-control` 头。
Nginx 的 expires 指令本质上是向响应头写入 Expires 和 Cache-Control: max-age=...,但它仅在成功生成响应体且 Content-Type 已确定时才生效。而在 SPA 的典型配置中(如 try_files $uri /index.html),当浏览器软重载(如 Ctrl+R 或点击刷新)时,Nginx 可能复用上游(如静态文件服务或内部重定向)已缓存的响应头,导致 Content-Type 未被重新评估——这正是你观察到的现象:首次加载时 Content-Type: text/html 存在,map 正确匹配 epoch;而软重载时该 header 缺失,$sent_http_content_type 为空字符串,map 默认回退至 default 1y,最终 index.html 被错误地缓存一年。
✅ 正确解法:弃用 expires + map 组合,改为基于 location 精准控制 Cache-Control:
server {
listen $PORT;
# 静态资源(JS/CSS/图片等)长期缓存
location ~* \.(js|css|json|woff2?|ttf|eot|svg|png|jpg|gif)$ {
add_header Cache-Control "public, immutable, max-age=31536000";
try_files $uri =404;
}
# 关键:显式匹配 index.html,强制不缓存
location = /index.html {
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
add_header Expires "0";
try_files /index.html =404;
}
# 其他请求统一 fallback 到 index.html(SPA 路由)
location / {
add_header Access-Control-Allow-Origin "*";
try_files $uri /index.html;
sendfile on;
tcp_nopush on;
gzip on;
gzip_types text/html application/javascript text/css;
}
}? 关键说明:
- location = /index.html 是精确匹配,优先级高于通用 location /,确保所有对 /index.html 的直接请求(包括软重载触发的内部重定向)均命中此块;
- Cache-Control: no-cache, no-store, must-revalidate 是现代标准:no-store 禁止任何存储(最严格),must-revalidate 强制每次校验,no-cache 要求验证后再使用(兼容老客户端);
- Pragma 和 Expires 作为 HTTP/1.0 兼容补充,非必需但推荐保留;
- 静态资源使用 immutable + max-age=31536000(1年),配合内容哈希(如 main.a1b2c3.js)可安全长期缓存。
⚠️ 注意事项:
立即学习“前端免费学习笔记(深入)”;
- 切勿在 location / 中使用 map + expires 控制 HTML 缓存——$sent_http_content_type 是“已发送的响应头”,其值取决于响应生成阶段,不可靠用于条件判断;
- 若使用构建工具(如 Webpack/Vite),确保 index.html 本身不被 CDN 或反向代理二次缓存,必要时在 CDN 层单独配置 /index.html 的缓存策略;
- 部署后可用 curl -I https://your-domain.com/index.html 验证响应头是否包含 Cache-Control: no-cache...。
通过精准的 location 分流与语义清晰的 Cache-Control,可彻底解决 SPA 中 HTML 缓存失效问题,兼顾兼容性与可靠性。



















