map 指令用于预计算式变量映射,通过 $http_content_type 控制缓存开关与 TTL:JSON 不缓存,HTML 缓存 5 分钟,其余默认 1 小时;需注意请求头来源、正则引号、bypass/no_cache 区别及空 Content-Type 显式处理。
理解 map 块在缓存策略中的作用
map
是 Nginx 的核心模块
提供的指令,用于根据某个变量(如请求头、URI、参数等)的值,映射出一个新的变量。它不是条件判断,而是**预计算式变量赋值**——在请求处理早期就完成匹配,性能高效且可被缓存机制直接引用。
用它控制
行为的关键在于:将
(客户端发来的请求体 MIME 类型)映射为一个缓存开关或缓存区域名,再通过
、
等指令联动生效。
配置示例:按 Content-Type 区分缓存启用与过期时间
以下是一个生产可用的配置片段,实现:
•
请求不缓存
•
缓存 5 分钟
• 其他类型(如
、
)缓存 1 小时
}
Nginx
在宝塔面板中轻松管理Nginx高性能Web服务器。提供可视化配置反向代理、负载均衡、SSL证书及HTTP缓存功能,一键优化高并发性能,助您高效搭建稳定、快速的网站运行环境。
下载
关键细节说明与避坑提示
该配置看似简洁,但有几个易错点必须注意:
Content-Type 来源是请求头,不是响应头
:
读取的是客户端发起请求时携带的
(如 POST/PUT 请求体格式),而非后端返回的响应类型。若想按响应类型缓存,应改用
,并配合
的 MIME 类型匹配语法(如
)
正则匹配需加引号和修饰符
:map 中使用
表示大小写不敏感正则;整个 pattern 必须用双引号包裹,否则含斜杠(如
)会解析失败
proxy_cache_bypass 和 proxy_no_cache 逻辑不同
:
:当变量值为非空、非"0"、非"off"、非"false"时,跳过缓存直接转发
:当变量值为真时,即使命中缓存也不返回,而是重新请求上游并覆盖旧缓存
实际中常二者配合使用,确保“不缓存”的请求既不读也不写缓存
空 Content-Type 或缺失头需显式处理
:很多工具(如 curl 不带 -H)或浏览器表单提交可能不带
,此时
为空字符串,必须在 map 中用
明确匹配,否则走 default 分支导致误缓存
验证与调试方法
上线前务必用真实请求验证行为是否符合预期:
发送不同 Content-Type 的请求,观察响应头:
检查
是否为
/
/
,以及
值是否正确
查看缓存目录文件变化:
结合
后观察新请求是否生成缓存文件
开启 Nginx debug 日志(临时):
在 events 块中加
,并在 error_log 中设
,可追踪 map 匹配过程和缓存决策路径
ngx_http_map_moduleproxy_cache$http_content_typeproxy_cacheproxy_cache_bypassapplication/jsontext/htmlapplication/javascripttext/csshttp {
# 定义缓存区域
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;
# 根据 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;
}
}$http_content_typeContent-Type$upstream_http_content_typeproxy_cache_validproxy_cache_valid 200 302 10m text/html;~*application/jsonproxy_cache_bypass $cache_enabledproxy_no_cache $cache_enabledContent-Type$http_content_type""curl -H "Content-Type: application/json" -I http://your-domain/api/usercurl -H "Content-Type: text/html" -I http://your-domain/api/pageX-Cache-StatusMISSEDHITBYPASSX-Cache-Enabledfind /var/cache/nginx/api_cache -type f | head -5nginx -t && nginx -s reloaddebug_connection 127.0.0.1;error_log /var/log/nginx/debug.log debug;