在nginx中使用正则表达式重定向子域

时间:2012-03-06 05:56:44

标签: regex nginx

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;
}

因此最好使用正则表达式。

5 个答案:

答案 0 :(得分:27)

回答旧问题以帮助他人

使用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等网址重写为只有一个服务器指令的xxx.domainB.com。

答案 1 :(得分:10)

得与NGINX一起爱正则表达式!

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

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

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

这样做的原因如下:指向此服务器的每个subdomain.domain-name.tld(IP地址)会自动重定向到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

以上的正则表达式很棒,因为你可以随意扔任何东西,它会为你转换它。

答案 2 :(得分: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
}

会为你效劳。

答案 3 :(得分:1)

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

server {
      server_name .mydomain.com;

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

答案 4 :(得分: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中的相同子域。