动态资源缓存需结合响应特征动态判断:用map指令根据$sent_http_content_type设置$expires_time,再交由expires或proxy_cache_valid控制;代理时按http状态码分层缓存,避开用户个性化干扰,并通过curl和日志验证。

动态资源缓存过期不能靠静态规则硬写,得结合响应特征动态判断——核心是用 map 指令生成变量,再交给 expires 或 proxy_cache_valid 控制。
用 map 匹配 MIME 类型设过期时间
最稳妥的方式是依据实际返回的 Content-Type 决定缓存时长,避免仅靠文件后缀误判(比如 JS 文件被后端吐成 text/plain):
- 在
http块中定义映射:
map $sent_http_content_type $expires_time {
default "epoch";
~*^text/ "1h";
~*^image/ "1y";
~*^application/javascript "1h";
~*^application/css "1h";
~*^font/ "1y";
}
-
$sent_http_content_type是响应头里的真实类型,比$request_filename更可靠; - 正则前加
~*表示忽略大小写; -
default "epoch"表示未匹配时强制不缓存,防止继承意外配置。
然后在 location 中启用:
location / {
expires $expires_time;
add_header Cache-Control "public";
}
对代理动态内容用 proxy_cache_valid 分状态设过期
当 Nginx 作为反向代理缓存后端 API 或 HTML 页面时,应按 HTTP 状态码区分策略:
-
200、301、302成功响应可缓存较久(如 10 分钟); -
404可缓存短时间(如 1 分钟),避免反复穿透; -
any作为兜底,防止未显式声明的状态被缓存太久。
proxy_cache_valid 200 301 302 10m; proxy_cache_valid 404 1m; proxy_cache_valid any 1m;
注意:该指令必须配合 proxy_cache 和 proxy_cache_path 才生效,且只作用于代理响应,不控制浏览器本地缓存。
动态页面需绕过用户个性化干扰
含 Cookie、Session 或 User-Agent 差异的页面,直接缓存容易出错。建议:
- 用
proxy_cache_key剔除变动因子,例如去掉$cookie_sessionid; - 对登录态页面,可设
proxy_cache_bypass $cookie_auth,有认证 Cookie 就不走缓存; - 用
add_header X-Cache-Status $upstream_cache_status调试命中情况,常见值:HIT、MISS、BYPASS。
验证与调试要点
配置完别急着 reload,先确认关键行为是否符合预期:
- 用
curl -I查看响应头中的Cache-Control和Expires是否随资源类型变化; - 检查 Nginx 错误日志,确认
map变量是否被正确解析(如出现invalid number of arguments多因语法缩进或分号缺失); - 若缓存始终不生效,检查上游是否返回了
Cache-Control: no-cache或Set-Cookie,需用proxy_ignore_headers显式忽略。











