Nginx通过map指令基于User-Agent预判设备类型,推荐在http块中定义$is_mobile等变量,再在server中用if结合proxy_pass、root或return实现PC与移动端分流,兼顾性能与可维护性。

Linux 下 Nginx 通过请求头(主要是 User-Agent)区分移动端和 PC 端,核心是利用 $http_user_agent 变量做正则匹配,并结合 map 或 if 实现分流。推荐用 map,它性能更好、逻辑更清晰,且避免 if 在 location 外部的限制问题。
用 map 指令预定义设备类型变量
在 http 块(全局)中定义,不写在 server 或 location 里:
http {
# 判断是否为移动端:匹配常见移动 UA 特征
map $http_user_agent $is_mobile {
default 0;
~*(android|iphone|ipad|ipod|blackberry|webos|windows\s+ce|iemobile|opera\s+mobi|mobile) 1;
}
<pre class="brush:php;toolbar:false;"># 可选:反向定义是否为 PC(便于理解)
map $http_user_agent $is_pc {
default 0;
~*(windows\s+nt|macintosh|linux.*x11|ubuntu|fedora|centos) 1;
}
...}
这样后续所有 server 都能直接使用 $is_mobile 或 $is_pc,值为字符串 "0" 或 "1",可用于条件判断。
在 server 中根据设备类型分流
有三种常用方式,按推荐顺序排列:
Linux系统管理专家,覆盖12大模块:用户权限、SSH、存储、网络、systemd、防火墙、日志监控、备份恢复、TLS证书、Ansible、容器、IaC。提供配置、验证、加固、监控、备份、自动化、故障排查、回滚闭环。关键词:useradd、sudo、sshd_config、chmod、SEL...
-
方式一:反向代理到不同后端服务(最灵活)
适合前后端分离、PC 和 Mobile 各自有独立应用服务器的情况:
upstream pc_backend { server 127.0.0.1:8080; }
upstream mobile_backend { server 127.0.0.1:8081; }
<p>server {
listen 80;
server_name example.com;</p><pre class="brush:php;toolbar:false;">location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
if ($is_mobile = "1") {
proxy_pass http://mobile_backend;
break;
}
proxy_pass http://pc_backend;
}}
-
方式二:静态资源路径切换(轻量级)
适合 PC 和 Mobile 共用一个 Nginx,但前端 HTML/CSS/JS 分开放在不同目录:
server {
listen 80;
server_name example.com;
<pre class="brush:php;toolbar:false;">location / {
if ($is_mobile = "1") {
root /usr/share/nginx/html/mobile;
index index.html;
break;
}
root /usr/share/nginx/html/pc;
index index.html;
}}
-
方式三:302 重定向到不同域名(用户可见跳转)
适合已部署 m.example.com 和 www.example.com 两套站点:
server {
listen 80;
server_name example.com;
<pre class="brush:php;toolbar:false;">location / {
if ($is_mobile = "1") {
return 302 https://m.example.com$request_uri;
}
# PC 用户正常访问
}}
增强判断准确性的实用建议
User-Agent 容易被伪造或遗漏,单靠它不够健壮。可叠加以下策略提升可靠性:
- 加入 Cookie 判断:用户手动切换过视图后,写入
ACCESS_TERMINAL=mobile,优先读取该 Cookie - 对原生 App 流量单独处理:App 的 UA 通常含明确标识(如
MyApp/4.2 (iOS)),可额外映射为$is_app - 避免过度匹配:像
curl、Java、Wget这类工具 UA 不代表真实终端,除非业务需要,否则不要纳入移动判断 - 测试时用 curl 模拟不同 UA:
curl -H "User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X)" http://localhost
注意事项与避坑点
实际配置中容易出错的地方:
-
map必须放在http块顶层,不能嵌套在server或location内 -
if在location中可用,但在server级别使用可能引发不可预期行为,不推荐 -
root和alias行为不同:用root时路径会拼接 location 路径;用alias是直接替换,注意末尾斜杠 - 正则中的空格要转义为
\s+,比如windows\s+nt,否则匹配失败 - 修改配置后务必执行
nginx -t检查语法,再nginx -s reload生效

















