Nginx可通过map指令将$http_user_agent映射为结构化变量(如$version),再结合proxy_pass或try_files实现按设备类型分发;map须定义在http块顶层,支持~*不区分大小写正则、复合键匹配及default兜底。

可以通过 Nginx 的 map 指令结合 $http_user_agent 或 $http_accept 等变量,将请求按客户端设备类型分类,再配合 proxy_pass 或 try_files 实现不同版本的转发或静态资源分发。
定义设备类型映射关系
在 http 块中使用 map 创建一个变量(如 $version),根据 User-Agent 字符串识别常见设备:
map $http_user_agent $version {
default "web";
~*android|mobile|blackberry|webos|iphone|ipod|iemobile|symbian "mobile";
~*tablet|ipad|kindle|silk|nexus.*[34] "tablet";
}说明:
- 正则匹配不区分大小写(~*);
- 顺序重要,更具体的规则建议放在前面(如 ipad 在 mobile 之前,避免被误判为 mobile);
- default 是兜底值,确保变量总有值,避免后续配置出错。
在 server 或 location 中使用映射结果
根据 $version 变量决定如何处理请求。常见方式有两类:
-
反向代理到不同后端服务:例如将 mobile 请求转发到
http://mobile-api/,web 请求到http://web-api/ -
静态资源路径重写:例如用
try_files优先尝试/mobile/index.html,再回退到/web/index.html
示例(反向代理):
location /api/ {
proxy_pass http://backend-$version/;
proxy_set_header Host $host;
}需提前在 upstream 中定义 backend-mobile、backend-web 等。
补充判断:兼顾现代特征检测(可选)
单靠 User-Agent 不够可靠(可伪造、更新滞后)。可叠加简单 HTTP 头判断,比如检查是否带 Sec-CH-UA-Mobile(Chrome 的客户端提示头):
map $http_sec_ch_ua_mobile $is_mobile_hint {
"?1" "1";
default "0";
}
<p>map $is_mobile_hint:$http_user_agent $version {
default "web";
"1:~<em>" "mobile";
"~</em>android|iphone|ipod|mobile" "mobile";
}注意:map 支持复合键(用冒号连接多个变量),适合多条件组合判断。
验证与调试技巧
上线前建议确认映射逻辑是否生效:
- 临时在响应头中输出变量值:
add_header X-Version $version; - 用 curl 模拟不同 UA:
curl -H "User-Agent: Mozilla/5.0 (iPhone..." http://your.site/ - 查看 Nginx 错误日志,确认 map 变量未报
undefined variable
确保 map 块位于 http 级别,且在引用它的 server 块之前加载。


















