Nginx移动端跳转关键在于避免死循环:用map提前提取$is_mobile变量、return 302而非rewrite permanent、通过参数或Cookie支持“电脑版”回切、拆分PC与移动端为独立server块。

Nginx 做移动端跳转,核心不是“能不能”,而是“怎么跳才不翻车”——if 用错、rewrite 和 return 混用、没处理“电脑版”回切,三者任一出问题,用户就会卡在死循环里。
用 map 提前提取设备类型,别在每个 location 里重复写正则
直接在 http 块顶部定义 map,比在 server 或 location 里反复用 if ($http_user_agent ~* ...) 更安全、更高效:
map $http_user_agent $is_mobile {
default 0;
~*[Mm]obile 1;
~*[Aa]ndroid 1;
~*[iI]phone 1;
~*[iI]pad 1;
~*[Bb]lack[Bb]erry 1;
~*[Oo]pera [Mm]ini 1;
}这样后续所有逻辑都基于 $is_mobile 变量,避免正则多次编译、语义不清。注意:map 不支持嵌套或复杂逻辑,只做单层匹配;大小写敏感靠 ~* 控制,别漏掉星号。
return 302 是首选,rewrite ... redirect 容易误配成 permanent
跳转必须明确是临时重定向(302),否则浏览器/CDN 缓存后改配置也无效。常见错误:
- 写成
rewrite ^(.*) https://m.example.com$1 permanent;→ 实际是 301,强缓存,改完重启也不生效 - 在同一个
server块里既对 PC 站加跳转,又对手机站加“反向跳回”,没加拦截条件 → 用户点“电脑版”立刻被跳回,无限循环
正确写法(放在对应 server 块内):
if ($is_mobile = 1) {
return 302 https://m.example.com$request_uri;
}或者更稳妥的写法(避免 if 在某些上下文中的限制):
location / {
if ($is_mobile = 1) {
return 302 https://m.example.com$request_uri;
}
# PC 站正常服务
}用户手动切回 PC 版,必须绕过 UA 判断
光靠 $http_user_agent 无法解决“我在 m.example.com 点了‘电脑版’,结果下一秒又被跳回来”的问题。Nginx 在请求到达时已做完 UA 判断,前端 JS 来不及干预。
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
解决方案只有两个,且必须二选一:
- 跳转时带上参数:
return 302 https://m.example.com$request_uri?desktop=1;,然后在移动端server块中加判断:if ($args ~ desktop=1) { set $is_mobile 0; } - 用 Cookie:
if ($http_cookie ~* "desktop=1") { set $is_mobile 0; },前端点击“电脑版”时设 Cookie,Nginx 读取后跳过 UA 匹配
参数方式更轻量,但需确保所有跳转链接都带该参数;Cookie 方式更稳定,但要考虑跨域和 HttpOnly 设置。
别把 PC 和移动端配置写在同一个 server 块里硬拼
有人试图在一个 server 块里同时处理 www 和 m 的跳转逻辑,结果条件交叉、优先级混乱。比如:
if ($host = "www.example.com" && $is_mobile = 1) { ... }
if ($host = "m.example.com" && $is_mobile = 0) { ... }这种写法极易漏边角 case,且 Nginx 的 if 执行顺序和嵌套行为不可靠。推荐做法是拆成两个独立 server 块:
- 一个监听
www.example.com,只做“PC 站 → 移动端跳转” - 另一个监听
m.example.com,只做“移动端 → PC 站跳转(带 desktop 参数或 Cookie 拦截)”
每个块职责单一,调试和上线都清晰。别为了“省一个 server 块”埋下线上循环跳转的坑。
真正难的不是写几行配置,而是让跳转逻辑在各种组合下(首次访问、手动切版、刷新、分享链接、搜索引擎爬虫)都保持可预期。UA 字符串本身就不标准,map 的匹配边界、return 和 rewrite 的缓存语义、用户状态的传递方式——这三处任意一处松动,整个适配就不可靠。

















