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;
}
因此最好使用正则表达式。
答案 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中的相同子域。