《Nginx跳转代码》区分PC/手机/爬虫实现域名自动跳转

[复制链接]
sheep 发表于 1 小时前 | 显示全部楼层 |阅读模式
Nginx 访问分流规则,依靠 UA 头判断访客类型,仅真人桌面 PC 浏览器触发 302 重定向到 www1 域名;移动端、爬虫脚本、iPad 桌面模式均不参与跳转。

  1. # 1) 提取基础域名:移除 www. / www1. 前缀,得到裸域名
  2. set $base_domain "$host";
  3. # 匹配 www1.开头的域名,捕获后面裸域名部分赋值给base_domain
  4. if ($host ~* "^www1\.(.+)$") {
  5.     set $base_domain $1;
  6. }
  7. # 匹配 www.开头的域名,捕获后面裸域名部分赋值给base_domain
  8. if ($host ~* "^www\.(.+)$") {
  9.     set $base_domain $1;
  10. }

  11. # 2) UA 判断:识别是否为真实PC桌面浏览器访问
  12. set $is_pc 0;
  13. # 匹配桌面操作系统UA标识,初步标记为PC访问
  14. if ($http_user_agent ~* "(windows\s*nt|macintosh|mac\s*os\s*x|x11|cros|linux\s*(x86|amd64|i686))") {
  15.     set $is_pc "Y";
  16. }
  17. # 存在移动端关键字则强制取消PC标记(包含iPad、开启桌面模式手机等移动设备)
  18. if ($http_user_agent ~* "(mobile|iphone|ipad|ipod|android|windows\s*phone|blackberry|opera\s*mini|ucweb|meego|silk|kindle|playbook|nintendo|playstation|wii)") {
  19.     set $is_pc 0;
  20. }
  21. # 匹配各类爬虫、机器人、扫描工具、程序请求UA,取消PC标记,不执行跳转
  22. if ($http_user_agent ~* "(bot|spider|crawl|slurp|scan|fetch|semrush|ahrefs|petalbot|bytespider|yandex|baidu|google|bing|sogou|exabot|ia_archiver|360|curl|wget|python|java|libwww|scrapy|go-http|headless|GPTBot|ChatGPT-User|Applebot|DoubaoBot|DeepSeekBot|QwenBot|YuanbaoBot|WenxinBot|KimiBot|ClaudeBot|PerplexityBot|ZhipuBot)") {
  23. set $is_pc 0;
  24. }

  25. # 3) 满足条件:PC访问且当前域名不是www1.开头,则302重定向至www1.裸域名
  26. set $go_www1 0;
  27. # 判定为PC桌面浏览器,开启跳转标识
  28. if ($is_pc = "Y") {
  29.     set $go_www1 1;
  30. }
  31. # 当前访问域名已经是www1.开头,关闭跳转标识,防止循环跳转
  32. if ($host ~* "^www1\.") {
  33.     set $go_www1 0;
  34. }
  35. # 跳转标识生效,执行302临时重定向,保留原始请求URI
  36. if ($go_www1 = 1) {
  37.     return 302 http://www1.$base_domain$request_uri;
  38. }
复制代码
Nginx 配置逐段完整解释

这段是 Nginx server {} 内的变量+判断逻辑,实现一套访问跳转规则,核心业务逻辑:
桌面PC真实浏览器访问 → 自动302重定向到 www1.根域名✅ 已经访问 www1.xxx.com、手机/平板、爬虫、脚本工具 → 不跳转,正常访问当前地址
下面分段拆解每一块代码:
1. 提取基础域名:剥离 www / www1 前缀

set $base_domain "$host";if ($host ~* "^www1\.(.+)$") {    set $base_domain $1;}if ($host ~* "^www\.(.+)$") {    set $base_domain $1;}
  • $host:请求访问的域名(例如 www. 域名.com / www1. 域名.com /  域名.com)
  • 正则 ~*:不区分大小写匹配
  • 逻辑:
    • 如果域名以 www1. 开头,把 www1. 去掉,剩下部分存入 $base_domain
    • 如果域名以 www. 开头,把 www. 去掉,剩下部分存入 $base_domain
      示例:www. 域名.com → base_domain =  域名.comwww1. 域名.com → base_domain =  域名.com 域名.com → base_domain =  域名.com

2. UA 判断:区分【真实PC桌面浏览器】$is_pc

set $is_pc 0;# 先认桌面系统标识if ($http_user_agent ~* "(windows\s*nt|macintosh|mac\s*os\s*x|x11|cros|linux\s*(x86|amd64|i686))") {    set $is_pc "Y";}# 移动端关键字优先排除if ($http_user_agent ~* "(mobile|iphone|ipad|ipod|android|windows\s*phone|blackberry|opera\s*mini|ucweb|meego|silk|kindle|playbook|nintendo|playstation|wii)") {    set $is_pc 0;}# 爬虫/Bot/脚本工具排除if ($http_user_agent ~* "(bot|spider|crawl|slurp|scan|fetch|semrush|ahrefs|petalbot|bytespider|yandex|baidu|google|bing|sogou|exabot|ia_archiver|360|curl|wget|python|java|libwww|scrapy|go-http|headless|GPTBot|ChatGPT-User|Applebot|DoubaoBot|DeepSeekBot|QwenBot|YuanbaoBot|WenxinBot|KimiBot|ClaudeBot|PerplexityBot|ZhipuBot)") {    set $is_pc 0;}$http_user_agent = 浏览器/客户端UA头,判断顺序:
  • 初始 $is_pc = 0(默认不是PC)
  • 如果UA包含桌面系统关键词(Windows NT、MacOS、Linux桌面、ChromeOS等)→ 标记 $is_pc="Y" 暂定是PC
  • 优先级更高:只要匹配移动端关键词 → 强制重置为0
    重点:哪怕UA带有Windows/Mac字样,只要同时出现mobile/android/iphone等,判定为移动端(用来拦截iPad、手机桌面模式浏览器)
  • 优先级最高:匹配爬虫、机器人、curl/wget/python脚本、各大搜索引擎Bot、AI爬虫 → 强制重置为0
简单一句话:只有【纯桌面系统UA、不含移动端标识、不是爬虫脚本】才会被认定为PC浏览器 $is_pc="Y"
3. 判断是否需要跳转到 www1.xxx.com

set $go_www1 0;if ($is_pc = "Y") {    set $go_www1 1;}if ($host ~* "^www1\.") {    set $go_www1 0;}if ($go_www1 = 1) {    return 302 http://www1.$base_domain$request_uri;}逻辑流程:
  • 默认 $go_www1=0,不跳转
  • 如果判定是PC浏览器 → 开启跳转标记 $go_www1=1
  • 如果当前域名已经是 www1. 开头 → 关闭跳转(防止无限循环重定向)
  • 如果最终 $go_www1=1:
    • 执行 302临时重定向
    • 地址:http://www1.基础域名 + 当前请求路径
完整场景举例(域名  域名.com)

场景1:电脑Chrome访问 https:// 域名.com

  • base_domain =  域名.com
  • UA识别为Windows,无移动端关键词、不是爬虫 → is_pc=Y
  • host不是www1. → go_www1=1
  • 302跳转 → http://www1. 域名.com/当前路径
场景2:电脑Chrome直接访问 www1. 域名.com

触发 $host ~ "^www1." → go_www1=0,不跳转,正常打开
场景3:手机Safari访问  域名.com

UA匹配iphone/mobile → is_pc=0,不跳转,直接访问原域名
场景4:百度爬虫、curl、python脚本访问

匹配bot/curl关键词 → is_pc=0,不跳转
场景5:iPad浏览器(桌面模式)

UA带有ipad关键词 → 被强制判定非PC,不跳转
⚠️ 重要缺陷提醒(Nginx经典坑)

Nginx 的 if 是指令,不支持多条件连贯判断,且存在陷阱,同时这段代码有几个问题:
  • 跳转写死 http://,如果网站启用HTTPS,会出现HTTP跳转,产生混合内容/证书问题;建议改成 $scheme://return 302 $scheme://www1.$base_domain$request_uri;
  • 302是临时重定向;如果希望永久跳转,可以改为301
  • Nginx多个串行 if 写法可读性差,复杂场景容易出现预期外逻辑
  • 部分小众客户端UA可能漏判;
  • 无限跳转防护仅判断host是否www1.,正常情况下够用
一句话极简总结

凡是真人用电脑桌面浏览器访问主域名/www域名,自动跳转到www1.域名;手机、平板、爬虫、脚本、已经在www1域名上的访问,全都保持原样不跳转。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注公众号
Archiver|手机版|小黑屋|社区规范|绵羊优创

相关侵权、举报、投诉及建议等,请发 E-mail:2363400792@qq.com

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.|京ICP备19037745号-2公安备案京公网安备11011502037529号

在本版发帖
关注公众号
QQ客服返回顶部
来点音乐
优聚封面
歌曲名称
歌手名称
0:00 0:00
顺序播放
歌词加载中...