移动端必须用302跳转至https://m.example.com并保留$request_uri,避免301导致SEO权重错配;桌面端仅做80→443的301跳转;UA判断须在listen 443 ssl块外层进行,且需透传X-Forwarded-Proto头。

移动端域名适配必须用 302 重定向,不能用 301 —— 这是避免 SEO 权重错配、防止搜索引擎把手机站误判为主站的关键前提。
只在 HTTP(80 端口)做基础跳转,不判断 UA
HTTP 请求进来时,先统一跳到 HTTPS,但不做移动端识别,也不跳 m 域名。这一步只是协议升级:
- 用
return 301 https://$host$request_uri; - 确保
$request_uri完整保留路径和查询参数 - 不要在这里写 if 判断 UA,否则可能漏掉或误判
HTTPS 下再做 UA 判断并 302 跳 m 域名
所有移动端逻辑都放在 listen 443 ssl 的 server 块里,且必须在 location 外层:
- 正则推荐:
if ($http_user_agent ~* "(Mobile|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini)") { return 302 https://m.example.com$request_uri; } -
$request_uri是关键:它包含完整路径 + query string,比$uri更安全 - 跳转目标必须是已部署有效 SSL 证书的域名,否则用户看到“您的连接不是私密连接”
PC 流量不参与跳转,直接走原域名 HTTPS
桌面端访问 www.example.com 时,不做任何 UA 判断,也不跳 m 站,只保证走 HTTPS 即可:
- HTTPS server 块里不写 UA 相关 if
- location / 正常指向 PC 站静态资源或反向代理后端
- 若用户手动加
?desktop=1,可在 if 条件中排除:if ($http_user_agent ~* ... && $args !~ desktop=1) { ... }
注意透传 X-Forwarded-Proto 头(尤其用 CDN 或负载均衡时)
如果前端有代理层,Nginx 必须正确识别原始协议,否则 HTTPS 判断会失效:
- 在 server 块顶部加:
set $real_scheme $scheme; - 若有 CDN,加:
if ($http_x_forwarded_proto = "https") { set $real_scheme "https"; } - 后续 UA 判断仍基于 443 端口,但内部逻辑可参考
$real_scheme防止误跳


















