Nginx通过$http_user_agent匹配设备类型实现移动端与PC端自动适配跳转:用rewrite做同域名内静默重写(需last标志+map预判+路径防重写),用return 302做跨域重定向(需$request_uri+禁用301),并支持Cookie或参数控制手动切换,避免跳转循环。

移动端与 PC 端自动适配跳转,核心是识别设备类型并导向对应资源——Nginx 不做设备检测,但能通过 $http_user_agent 变量匹配常见标识,再用 rewrite(内部重写)或 return(外部重定向)实现路由。关键区别在于:是否要改浏览器地址栏、是否跨域名、是否影响缓存和 SEO。
用 rewrite 做静默路径重写(同域名内)
适合移动端页面放在 /m/ 子目录下,用户访问 example.com/xxx 时,服务端悄悄返回 /m/xxx 的内容,地址栏不变。
- 必须搭配
last标志,让重写后重新进入 location 匹配流程,否则可能找不到 index 文件 - 推荐先用
map预定义$is_mobile,避免每次请求都跑正则,提升性能 - 加条件限制,防止重复重写(比如已进
/m/还继续重写)
示例配置:
map $http_user_agent $is_mobile {
default 0;
~*[Mm]obile 1;
~*[Aa]ndroid 1;
~*[iI]phone 1;
~*[iI]pad 1;
}
server {
location / {
if ($is_mobile = 1) {
rewrite ^/(.*)$ /m/$1 last;
}
root /var/www/html;
index index.html;
}
location /m/ {
root /var/www/html;
index index.html;
}
}
用 return 做客户端重定向(跨域名或强跳转)
当 PC 站是 www.example.com、手机站是 m.example.com 时,应使用 return 302 跳转,保留完整路径和参数,且语义清晰、不触发二次 location 匹配。
- 务必用
$request_uri(含 query string),不用$uri(不含参数) - 禁用
301 permanent,避免浏览器/CDN 强缓存导致后续修改失效 - PC 站配置跳转逻辑;手机站需单独加反向拦截,否则点“电脑版”会立刻被跳回
PC 站配置片段:
if ($is_mobile = 1) {
return 302 https://m.example.com$request_uri;
}
支持用户手动切换(防跳转循环)
仅靠 UA 无法记住用户偏好。点击“电脑版”时,应在 URL 中带上 ?desktop=1 或设置 Cookie,Nginx 捕获后跳过自动跳转逻辑。
- 在 PC 站跳转前加判断:
if ($args ~ desktop=1) { break; } - 更可靠的做法是读取 Cookie:
map $cookie_device $skip_redirect { ~*pc 1; default 0; },再结合if ($skip_redirect = 0) { return 302 ... } - 手机站的 Nginx 配置中也要检查该标记,避免双向跳转死循环
避坑要点
实际配置中最容易出错的几个地方:
-
if不能嵌套,也不能出现在 server 级别过多位置;优先用map提前计算变量 - iPad UA 通常不含
mobile,必须显式匹配ipad,否则被当成桌面设备 - Chrome DevTools 模拟器也会带
Mobile字段,单靠这个词会误判,需组合多个关键词 - CDN 或浏览器缓存 302 时,可能导致跳转失效或延迟生效,建议测试时禁用缓存


















