Nginx 实现动态过期策略需基于响应头(如 $sent_http_content_type)用 map 动态设 expires,对哈希资源加 immutable,代理时按状态码分级缓存,并剔除 Cookie 等变动因子保障动态页面缓存安全。

要让 Nginx 对不同文件类型实现动态过期策略,关键不是写死时间,而是根据响应真实特征(比如 Content-Type)或请求上下文(比如是否带哈希、是否含 Cookie)实时决定缓存时长。静态后缀匹配只是基础,真正灵活可靠的做法依赖 map + 变量驱动 和 分层代理缓存控制。
用 map 指令按响应头动态设过期时间
比靠文件后缀更准的是看后端实际返回的 Content-Type —— 它由 $sent_http_content_type 暴露,不受 URL 命名干扰(例如后端把 JS 返回成 text/plain 也能被识别):
- 在
http块中定义映射:
default "epoch";
~*^text/ "1h";
~*^image/ "1y";
~*^application/javascript "1h";
~*^application/css "1h";
~*^font/ "1y";
}
- 正则前加
~*表示忽略大小写;default "epoch"强制未匹配项不缓存,避免继承默认配置; - 在
location中直接使用该变量:
expires $expires_time;
add_header Cache-Control "public";
}
对指纹化静态资源启用 immutable 长期缓存
当文件名含哈希(如 app.abc123.js),内容不变则 URL 不变,可放心设一年且加 immutable,浏览器将跳过验证请求:
- 用正则精准匹配哈希特征:
add_header Cache-Control "public, max-age=31536000, immutable" always;
}
-
always确保即使返回 304 或错误状态也携带该头; - 没哈希的通用资源(如
logo.png)建议设max-age=2592000(30 天),不加immutable;
代理动态内容时按 HTTP 状态码分级缓存
Nginx 作为反向代理时,缓存逻辑应聚焦响应本身而非路径——成功响应可缓久些,失败或临时响应缓短些,避免穿透放大:
- 必须配合
proxy_cache和proxy_cache_path才生效:
proxy_cache_valid 404 1m;
proxy_cache_valid any 1m;
-
any是兜底,防止未显式声明的状态被意外长期缓存; - 注意:该指令只影响 Nginx 本地代理缓存,不影响浏览器缓存;
绕过个性化干扰,保障动态页面缓存安全
含登录态、设备判断、A/B 测试参数的页面不能简单缓存。需用键值和绕过机制隔离:
- 精简
proxy_cache_key,剔除变动因子:
- 跳过缓存:有用户 Cookie 就不查缓存(
proxy_cache_bypass $cookie_sessionid); - 禁止缓存:管理员访问或调试参数时不写入(
proxy_no_cache $cookie_admin $arg_debug); - 用
add_header X-Cache-Status $upstream_cache_status查看命中情况(HIT/MISS/BYPASS);











