You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Map配置Nginx Expires Header,页面重载时失效问题排查

问题描述

我有一个单页应用,不希望index.html文件被缓存(否则发布新版本后,用户浏览器会加载缓存的旧index.html,导致关联旧打包JS文件)。我配置的Nginx模板如下:

map $sent_http_content_type $expires {
 text/html epoch;
 default 1y;
}

server {
 listen $PORT;
 ...
 location / {
   add_header Access-Control-Allow-Origin *;
   try_files $uri /index.html;
   sendfile on;
   expires $expires;
   tcp_nopush on;
   gzip on;
   gzip_types text/html application/javascript text/css;
 }
 ...
}

首次加载页面时,index.html的Expires头设置正确,但软重载页面时,Expires被设为1年。补充:首次加载/硬加载index.html时,响应头包含Content-Type:text/html,但软重载时该头消失。


问题原因

核心问题出在软重载时浏览器发送条件请求,Nginx返回304状态码的场景:

  • 首次/硬加载时,服务器返回200状态码,响应头包含Content-Type:text/html,map指令匹配到text/html规则,设置Expires: epoch(禁止缓存)。
  • 软重载时,浏览器会带上If-Modified-Since或If-None-Match这类条件请求头,Nginx判断文件未修改时返回304 Not Modified。此时响应头不会包含Content-Type这类实体头,导致$sent_http_content_type变量为空,map匹配到default规则,设置Expires: 1y。

解决方案

不要依赖$sent_http_content_type变量来控制index.html的缓存,直接针对index.html做单独配置,避免304场景下的变量失效问题:

方案1:单独配置index.html的location(推荐)

这种方式更高效,且符合Nginx的配置最佳实践:

# 单独处理index.html,强制禁止缓存
location = /index.html {
    expires epoch;
    add_header Cache-Control "no-cache, no-store, must-revalidate";
    add_header Pragma "no-cache";
    add_header Expires "0";
}

location / {
    add_header Access-Control-Allow-Origin *;
    try_files $uri /index.html;
    sendfile on;
    expires 1y; # 其他静态资源缓存1年
    tcp_nopush on;
    gzip on;
    gzip_types text/html application/javascript text/css;
}

方案2:在原有location内判断请求URI

如果不想拆分location,可以通过判断请求URI来设置缓存规则(此场景下if的使用是安全的):

map $sent_http_content_type $expires {
 default 1y;
}

server {
 listen $PORT;
 ...
 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;

   # 针对index.html强制禁止缓存
   if ($request_uri = /index.html) {
       expires epoch;
       add_header Cache-Control "no-cache, no-store, must-revalidate";
       add_header Pragma "no-cache";
       add_header Expires "0";
   }
   # 其他资源使用默认缓存规则
   if ($request_uri != /index.html) {
       expires $expires;
   }
 }
 ...
}

内容的提问来源于stack exchange,提问作者Spring Memory

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 13:05:00