【问题标题】:Redirecting a subdomain with a regular expression in nginx在 nginx 中使用正则表达式重定向子域
【发布时间】:2012-03-23 15:10:11
【问题描述】:

nginx 文档说server_name directive 支持正则表达式。我一直在努力尝试让一个微不足道的正则表达式工作。

我希望http://subdomain.mydomain.com 重定向到http://mydomain.com/subdomain

这是我的代码。

server {
  server_name "~^subdomain\.mydomain\.com$";
  rewrite ^ http://mydomain.com/subdomain;
}

另外,可能值得注意。在 nginx 配置文件的下方有一条规则:

server {
  server_name *.mydomain.com
  ...
}

我做错了什么?

更新:

有人建议我不要为此使用正则表达式...以提供更清晰的信息:琐碎的正则表达式仅用于故障排除。真正的正则表达式看起来更像...

server {
  server_name "~^.*(cvg|cincinnati)\.fakeairport(app)?\.(org|com)$";
  rewrite ^ http://fakeairport.com/cincinnati;
}

server {
  server_name "~^.*(lex|lexington)\.fakeairport(app)?\.(org|com)$";
  rewrite ^ http://fakeairport.com/lexington;
}

所以最好使用正则表达式。

【问题讨论】:

  • 对nginx一无所知,但为什么正则表达式的开头有波浪号?
  • 前导波浪号告诉 nginx 这是一个正则表达式。

标签: regex nginx


【解决方案1】:

就像评论一样。如果您想将所有子域级别重定向到第一个子域级别,例如,当您使用通配符 SSL 证书时,您可以使用:

server {
    listen 80;
    server_name ~^(.*)\.(?<subdomain>\w+).mydomain\.com$;
    return          301 https://$subdomain.mydomain.com$request_uri; 
}

server {
    listen 80;
    server_name ~^(?<subdomain>\w+).mydomain\.com$;
    return          301 https://$subdomain.mydomain.com$request_uri;
}

第一个是用于将 http 多级子域重定向到 https 中的第一个子域级别。下一个是将http中的一级子域重定向到https中的相同子域。

【讨论】:

    【解决方案2】:

    一定要喜欢 NGINX 的正则表达式!

    由于我经常使用多个域名,并且我希望我的配置尽可能干净和坚如磐石,因此我几乎总是将正则表达式与 nginx 一起使用。

    在这种情况下,我使用以下正则表达式解决了它:

    server {
        listen 80;
        server_name ~^((?<subdomain>.*)\.)(?<domain>[^.]+)\.(?<tld>[^.]+)$;
        return 301 $scheme://${domain}.${tld};
    }
    

    它的作用如下:每个指向该服务器(IP 地址)的subdomain.domain-name.tld 都会自动重定向到domain-name.tld

    例如,www.myexampledomain.com 被重定向到 myexampledomain.com

    要回答这个问题,您还可以执行以下操作:

    server {
        listen 80;
        server_name ~^((?<subdomain>.*)\.)(?<domain>[^.]+)\.(?<tld>[^.]+)$;
        return 301 $scheme://${domain}.${tld}/${subdomain};
    }
    

    现在mysubdomain.myexampledomain.com 转换为myexampledomain.com/mysubdomain

    上面的正则表达式非常棒,因为您可以向它扔任何您喜欢的东西,它会为您转换它。

    【讨论】:

    • 在您的示例中,server_name 中的 RegEx 捕获非常有用!一个奇妙的好处是,我能够通过像这样切断子域来动态定义共享的root 路径:root /home/www-data/$domain.$tld/; 您的答案使用了更现代的技术,应该更新为公认的答案。
    【解决方案3】:

    回答一个老问题来帮助别人

    使用 nginx 1.1.19 您可以执行以下操作:

    server {
        server_name     ~^(?<subdomain>\w+)\.domainA\.com$;
    
        location / {
                rewrite ^ https://$subdomain.domainB.com$request_uri permanent;
        }
    }
    

    domainA.com 之前的子域被匹配并存储在变量 $subdomain 中,然后可以在重写中使用。 这会将 xxx.domainA.com 之类的 url 重写为 xxx.domainB.com,只有一个服务器指令。

    【讨论】:

    • 域名也可以包含破折号,所以正则表达式应该是~^(?&lt;subdomain&gt;[\w-]+)\.domainA\.com$
    【解决方案4】:

    如果您阅读server_name matching rules,您会看到前缀和后缀 server_names 在正则表达式名称之前被检查,但在确切的主机名之后。由于 *.mydomain.com 匹配,因此未测试正则表达式。它在配置中前面列出的事实没有什么区别。由于您只是尝试将单个主机名与您的正则表达式匹配,因此很简单:

    server {
      server_name subdomain.mydomain.com;
      rewrite ^ http://mydomain.com/subdomain$request_uri?;
    }
    
    server {
      server_name *.mydomain.com;
    
      # stuff
    }
    

    会为你工作。

    【讨论】:

    • 简单的正则表达式只是为了排除故障。关于我为什么需要使用正则表达式的更多详细信息已添加到原始问题中。
    • 啊,我应该意识到这一点。你用后缀域做什么?只要你有它,任何正则表达式服务器都不会匹配该后缀。
    • 我们的应用程序架构曾经使用大量子域,因此它被用作一个包罗万象的重定向任何没有特定重定向的附加子域。
    • 它是你唯一的包罗万象吗?如果是这样,那么您可以只在该服务器的监听上使用 default_server 标志而不是匹配后缀,然后您就可以使用正则表达式 + 映射来使您的重定向工作。
    【解决方案5】:

    我知道每个人都在说 nginx 配置文件中的 if is evil,但有时你无法绕过任何其他方式。

    server {
          server_name .mydomain.com;
    
          if ( $host ~ subdomain.mydomain.com ) {
                    rewrite ^(.*) http://mydomain.com/subdomain$1;
          }
    }
    

    【讨论】:

    • 你不应该在不需要的时候使用 if。那只是自找麻烦。
    • 正确,但正如您所暗示的,在某些情况下需要它并且如果配置正确(仅使用重写模块命令),使用它是完全安全的。 “如果”的问题不在于不应该使用,而在于理解使用。
    • 我真的厌倦了大多数人说“永远不要使用 IF”。如果禁止使用,为什么还要实施?!
    • 另外,我在我当前的实时配置中使用 if 语句,没有任何限制的麻烦,所以我认为 if 有它的一部分并且可以正确使用。不要盲目,也不要被四处流传的神话所迷惑。
    • 我还可以举出一种情况,映射和 if 可以真正加速 WordPress 网络。 petermolnar.eu/linux-tech-coding/…
    猜你喜欢
    • 2012-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多