必须用 return 302 实现移动端跳转:语义清晰、保留参数、避免缓存;ua 判断须置于 https server 块内 location 外,目标域名需有效 ssl 证书,并支持 desktop=1 绕过。

移动端自适应跳转时,Nginx 必须用 return 302 实现临时重定向,而不是 rewrite ... permanent 或 return 301。关键不是“能不能跳”,而是“怎么跳才不伤 SEO、不丢参数、不触发证书警告”。
必须用 return 302,不能用 rewrite permanent
-
return 302 https://m.example.com$request_uri;是推荐写法:性能高、语义清晰、保留完整路径和查询参数 - 避免
rewrite ^(.*)$ https://m.example.com$1 permanent;:301 会被浏览器和搜索引擎长期缓存,导致 PC 用户误入 m 站后难退回,权重错配
UA 判断要放在 HTTPS server 块里,且在 location 外
- 移动端跳转逻辑应写在
listen 443 ssl的 server 块中(不是 80 端口),否则 HTTP 请求进来时还没解密 UA,容易误判 - 判断位置必须在
location { ... }之外,否则可能被 location 优先匹配而跳过
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# UA 判断放这里,全局生效
if ($http_user_agent ~* "(Mobile|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini)") {
return 302 https://m.example.com$request_uri;
}
location / {
root /var/www/pc;
index index.html;
}
}
跳转目标必须带 $request_uri,且 m 站已配好有效证书
-
$request_uri包含路径 + 查询参数(如/product?id=123&ref=share),确保用户看到的页面和原始请求一致 -
https://m.example.com必须已部署合法 SSL 证书;若证书无效,跳过去直接白屏或显示“您的连接不是私密连接”
支持 desktop=1 参数绕过跳转
- 有些用户主动想看 PC 版,可通过加参数强制保留:
https://www.example.com/?desktop=1 - 在 if 判断里排除该情况:
if ($http_user_agent ~* "(Mobile|Android|iPhone|iPad)"
and $arg_desktop != "1") {
return 302 https://m.example.com$request_uri;
}
桌面端不参与 UA 判断,只做 80→443 301
- PC 流量不应跳 m 站,也不应受 UA 影响,只需统一强制 HTTPS:
server { listen 80; server_name www.example.com; return 301 https://$host$request_uri; }
不复杂但容易忽略











