Перенаправление субдомена с регулярным выражением в nginx
В документации nginx говорится, что директива server_name поддерживает регулярные выражения. Я бился головой о стену, пытаясь заставить работать даже тривиальное регулярное выражение.
Я хочу, чтобы 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 ответов
Чтобы ответить на старый вопрос, чтобы помочь другим
используя nginx 1.1.19 вы можете сделать следующее:
server {
server_name ~^(?<subdomain>\w+)\.domainA\.com$;
location / {
rewrite ^ https://$subdomain.domainB.com$request_uri permanent;
}
}
Субдомен до domainA.com сопоставляется и сохраняется в переменной $subdomain, которую затем можно использовать при перезаписи. Это переписывает URL как xxx.domainA.com в xxx.domainB.com только с одной директивой сервера.
Должен любить регулярные выражения с 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
,
Выше регулярное выражение прекрасно, потому что вы можете бросить в него все, что вам нравится, и он преобразует это для вас.
Если вы прочитаете правила сопоставления имя_сервера, то увидите, что префикс и суффикс имя_сервера проверяются перед именами регулярных выражений, но после точных имен узлов. Поскольку *.mydomain.com совпадает, регулярное выражение не проверяется. Тот факт, что он указан ранее в конфигурации, не имеет значения. Поскольку вы просто пытаетесь сопоставить одно имя хоста с вашим регулярным выражением, просто:
server {
server_name subdomain.mydomain.com;
rewrite ^ http://mydomain.com/subdomain$request_uri?;
}
server {
server_name *.mydomain.com;
# stuff
}
будет работать на вас.
Я знаю, что все говорят, является ли зло в конфигурационных файлах nginx, но иногда вы не можете обойтись иначе.
server {
server_name .mydomain.com;
if ( $host ~ subdomain.mydomain.com ) {
rewrite ^(.*) http://mydomain.com/subdomain$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.