nginx可通过map模块解析user-agent实现移动端浏览器差异化代理转发,如微信(micromessenger)、qq浏览器(mqqbrowser)、android chrome(chrome.mobile)、ios safari(iphone.safari|ipad.*safari),再结合proxy_pass动态路由至对应后端。

在 Nginx 中,proxy_pass 本身不直接识别“移动端特定浏览器”,但可以通过解析请求头(如 User-Agent)结合 if、map 或 location 匹配,实现对不同移动端浏览器(如 iOS Safari、Android Chrome、微信内置浏览器、QQ 浏览器等)的差异化代理转发。
用 map 模块预定义浏览器类型(推荐)
map 是高效、安全的变量映射方式,避免 if 在 location 外使用的限制。在 http 块中定义:
map $http_user_agent $backend_upstream {
~*MicroMessenger wechat_backend;
~*MQQBrowser qq_backend;
~*Chrome.*Mobile android_chrome_backend;
~*iPhone.*Safari ios_safari_backend;
~*iPad.*Safari ios_safari_backend;
default default_backend;
}然后在 server 或 location 中使用:
location /api/ {
proxy_pass http://$backend_upstream;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}用 if + location 实现细粒度控制(慎用)
若需更复杂逻辑(如同时检查 UA 和 query 参数),可在 location 内用 if 设置变量,再跳转或重写。注意:if 不能嵌套,且仅支持有限指令(set、return、rewrite):
- 先用
set $target ""初始化变量 - 用多个
if ($http_user_agent ~* "...") { set $target "https://m-api.example.com"; } - 最后用
proxy_pass $target(Nginx 1.13.2+ 支持变量 proxy_pass)
区分微信和普通移动端的关键细节
微信内置浏览器的 User-Agent 含 MicroMessenger,但常同时含 Mobile 和 WebKit,易与 Safari/Chrome 冲突。建议按优先级顺序匹配:
- 先匹配
MicroMessenger(微信) - 再匹配
MQQBrowser(QQ 浏览器) - 然后匹配
Chrome.*Mobile(Android Chrome) - 最后用
iPhone.*Safari|iPad.*Safari匹配 iOS Safari
正则末尾加 i 标志(如 ~*i)可忽略大小写,但 ~* 默认已忽略,无需重复。
验证与调试技巧
上线前务必测试 UA 字符串是否被准确捕获:
- 临时添加
add_header X-Detected-Browser $backend_upstream;返回响应头 - 用 curl 模拟请求:
curl -H "User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1" http://your-domain/api/test - 查看 access log 中的
$http_user_agent和自定义变量值











