map 指令用于预计算式变量映射,通过 $http_content_type 控制缓存开关与 TTL:JSON 不缓存,HTML 缓存 5 分钟,其余默认 1 小时;需注意请求头来源、正则引号、bypass/no_cache 区别及空 Content-Type 显式处理。

理解 map 块在缓存策略中的作用
map 是 Nginx 的核心模块 ngx_http_map_module 提供的指令,用于根据某个变量(如请求头、URI、参数等)的值,映射出一个新的变量。它不是条件判断,而是**预计算式变量赋值**——在请求处理早期就完成匹配,性能高效且可被缓存机制直接引用。
用它控制 proxy_cache 行为的关键在于:将 $http_content_type(客户端发来的请求体 MIME 类型)映射为一个缓存开关或缓存区域名,再通过 proxy_cache、proxy_cache_bypass 等指令联动生效。
配置示例:按 Content-Type 区分缓存启用与过期时间
以下是一个生产可用的配置片段,实现:
• application/json 请求不缓存
• text/html 缓存 5 分钟
• 其他类型(如 application/javascript、text/css)缓存 1 小时
http {
# 定义缓存区域
proxy_cache_path /var/cache/nginx/api_cache levels=1:2 keys_zone=api_cache:10m max_size=1g inactive=60m use_temp_path=off;
<pre class="brush:php;toolbar:false;"># 根据 Content-Type 映射缓存开关(on/off)
map $http_content_type $cache_enabled {
default "on";
"" "off"; # 无 Content-Type 头时禁用
"~*application/json" "off";
"~*text/html" "on";
}
# 映射缓存有效时间(单位秒)
map $http_content_type $cache_ttl {
default "3600"; # 默认 1h
"~*text/html" "300"; # HTML 5min
"~*application/json" "0"; # JSON 不缓存(设为 0 即忽略 Expires/Cache-Control)
}
server {
listen 80;
location /api/ {
proxy_pass http://backend;
# 启用缓存并引用映射变量
proxy_cache api_cache;
proxy_cache_valid 200 302 $cache_ttl;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
# 仅当 $cache_enabled == "on" 时才真正缓存
proxy_cache_bypass $cache_enabled;
proxy_no_cache $cache_enabled;
# 可选:透传原始 Content-Type 到响应头,便于调试
add_header X-Cache-Status $upstream_cache_status;
add_header X-Cache-Enabled $cache_enabled;
add_header X-Cache-TTL $cache_ttl;
}
}}
⚠️ 已弃用 — 该技能已拆分为两个独立技能,以提升模块化程度:**webchat-https-proxy**(HTTPS/WSS 反向代理)和 **webchat-voi...**
关键细节说明与避坑提示
该配置看似简洁,但有几个易错点必须注意:
-
Content-Type 来源是请求头,不是响应头:
$http_content_type读取的是客户端发起请求时携带的Content-Type(如 POST/PUT 请求体格式),而非后端返回的响应类型。若想按响应类型缓存,应改用$upstream_http_content_type,并配合proxy_cache_valid的 MIME 类型匹配语法(如proxy_cache_valid 200 302 10m text/html;) -
正则匹配需加引号和修饰符:map 中使用
~*表示大小写不敏感正则;整个 pattern 必须用双引号包裹,否则含斜杠(如application/json)会解析失败 -
proxy_cache_bypass 和 proxy_no_cache 逻辑不同:
-
proxy_cache_bypass $cache_enabled:当变量值为非空、非"0"、非"off"、非"false"时,跳过缓存直接转发 -
proxy_no_cache $cache_enabled:当变量值为真时,即使命中缓存也不返回,而是重新请求上游并覆盖旧缓存
-
-
空 Content-Type 或缺失头需显式处理:很多工具(如 curl 不带 -H)或浏览器表单提交可能不带
Content-Type,此时$http_content_type为空字符串,必须在 map 中用""明确匹配,否则走 default 分支导致误缓存
验证与调试方法
上线前务必用真实请求验证行为是否符合预期:
- 发送不同 Content-Type 的请求,观察响应头:
curl -H "Content-Type: application/json" -I http://your-domain/api/usercurl -H "Content-Type: text/html" -I http://your-domain/api/page
检查X-Cache-Status是否为MISSED/HIT/BYPASS,以及X-Cache-Enabled值是否正确 - 查看缓存目录文件变化:
find /var/cache/nginx/api_cache -type f | head -5
结合nginx -t && nginx -s reload后观察新请求是否生成缓存文件 - 开启 Nginx debug 日志(临时):
在 events 块中加debug_connection 127.0.0.1;,并在 error_log 中设error_log /var/log/nginx/debug.log debug;,可追踪 map 匹配过程和缓存决策路径










