必须用 return 302 实现移动端临时跳转:语义清晰、保留完整 $request_uri 参数、避免缓存;UA 判断须置于 HTTPS server 块顶层(443 端口、location 外),排除 desktop=1 绕过,目标域名需有效 SSL 证书。

移动端与 PC 端自适应布局中的临时重定向,核心是“不固化、不丢参、不伤 SEO”。Nginx 里必须用 return 302,而不是 rewrite permanent 或 return 301 —— 后者会被浏览器和搜索引擎长期记住,导致用户从手机点开链接后进 m 站,再切回桌面却卡在 m 域名下,PC 页面也难被正常收录。
HTTPS server 块内做 UA 判断,且必须在 location 外
HTTP 请求进来时还没解密 User-Agent,所以判断逻辑不能放在 80 端口块里,也不能塞进 location { } 里(容易被路径匹配提前截断)。正确位置是:
- 监听 443 ssl 的 server 块顶层,紧贴 ssl 配置下方
- 用 if 判断 $http_user_agent,正则覆盖主流移动标识:Mobile|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini
- 同时排除 ?desktop=1 参数,让用户可手动切回 PC 版
示例:
if ($http_user_agent ~* "(Mobile|Android|iPhone|iPad)" && $arg_desktop != "1") {return 302 https://m.example.com$request_uri;
}
跳转目标必须带 $request_uri,且 m 站已配好有效证书
$request_uri 包含完整路径和查询参数(比如 /product?id=123&utm_source=share),比 $uri 或 $args 单独拼接更可靠。漏掉它,用户可能被跳到首页,丢失来源信息。
- 目标域名如 https://m.example.com 必须已部署合法 SSL 证书;否则跳过去直接显示“您的连接不是私密连接”
- 不要写成 return 302 https://m.example.com/ —— 尾部斜杠 + 缺少 $request_uri = 强制归零
- 如果用了 CDN 或负载均衡,记得透传 X-Forwarded-Proto 头,否则 HTTPS 判断可能失效
PC 端只做协议升级,不参与设备判断
桌面流量不该被 UA 干扰,它的任务只有一个:确保走 HTTPS。
- 80 端口 server 块里只做 return 301 https://$host$request_uri;,不做任何 UA 检查
- 443 端口的 PC server 块里不写 if 判断,location / 正常指向 PC 静态资源或后端服务
- 这样 PC 用户始终留在 www.example.com,SEO 权重不分散,移动端也不受影响
验证是否真跳对了,别只看地址栏
浏览器地址栏变化只是表象,关键看底层响应是否干净。
- 用 curl -I http://www.example.com/test 访问,确认返回 HTTP/1.1 302 Found 和 Location: https://m.example.com/test?xxx
- 检查 Location 头是否唯一、协议正确、无多余 www 或 http 混用
- 用无痕模式多刷几次,防止旧缓存干扰测试结果











