2009-10-27 4 views
37

Я вижу Nginx HttpRewriteModule documentation есть пример, чтобы переписать на WWW-приставке домен не-WWW-приставке домена:Nginx переписывание без WWW-приставка домена WWW-приставки домена

if ($host ~* www\.(.*)) { 
    set $host_without_www $1; 
    rewrite ^(.*)$ http://$host_without_www$1 permanent; # $1 contains '/foo', not 'www.mydomain.com/foo' 
} 

Как я могу сделать обратное - переписать домен, не содержащий www-prefixed, в домен с префиксом www? Я думал, может быть, я мог бы сделать что-то вроде следующего, но Nginx не любит вложенную инструкцию if.

if ($host !~* ^www\.) {      # check if host doesn't start with www. 
    if ($host ~* ([a-z0-9]+\.[a-z0-9]+)) { # check host is of the form xxx.xxx (i.e. no subdomain) 
     set $host_with_www www.$1; 
     rewrite ^(.*)$ http://$host_with_www$1 permanent; 
    } 
} 

Кроме того, я хотел, чтобы это работало для любого доменного имени без явного говоря Nginx переписать domain1.com -> www.domain1.com, domain2.com -> www.domain2.com и т.д., так как у меня есть большое количество доменов для перезаписи.

ответ

13

Ну, я думаю, мне не нужен внешний оператор «if», так как я проверяю только домены формы xxx.xxx. Для меня работает следующее, хотя оно не является надежным. Дайте мне знать, если есть лучшее решение.

if ($host ~* ^([a-z0-9\-]+\.(com|net|org))$) { 
     set $host_with_www www.$1; 
     rewrite ^(.*)$ http://$host_with_www$1 permanent; 
    } 

Редактировать: Добавлен дефис к регулярному выражению, поскольку он является допустимым символом в имени хоста.

+0

как использовать это без если? – pahnin

15
if ($host !~* ^www\.) { 
    rewrite ^(.*)$ http://www.$host$1 permanent; 
} 
+1

Это не работает для меня, потому что я не хочу переписывать субдомены, такие как static.mydomain.com. Вероятно, я должен был сказать это в моем вопросе. Спасибо за Ваш ответ. – saltycrane

6
if ($host ~* ^[^.]+\.[^.]+$) { 
    rewrite ^(.*)$ http://www.$host$1 permanent; 
} 

Это возможно только, чтобы получить действительные имена узлов, так как запрос никогда не будет делать его на сервер в противном случае, так что нет необходимости строить свою собственную логику проверки.

57

As noted in the Nginx documentation, you should avoid using the if directive in Nginx where possible, потому что, как только у вас есть if в конфигурации сервер должен оценить каждый запрос, чтобы решить, следует ли соответствовать if или нет.

Лучшим решением будет несколько директив серверов.

server { 
     listen 80; 
     server_name website.com; 
     return 301 $scheme://www.website.com$request_uri; 
} 

server { 
     listen 80; 
     server_name www.website.com; 
     ... 
} 

Если вы пытаетесь служить SSL (HTTPS) с поддержкой сайта, вы получили более или менее трех различных вариантов.

  1. Настройте несколько IP-адресов, каждая из которых отвечает каждому серверу на свой IP-адрес (или разные порты, если это вариант для вас). Этим параметрам нужны SSL-сертификаты для на сайте.com и www.website.com, так что у вас есть сертификат дикой карты, сертификат UNI (несколько доменов) или просто два разных сертификата.
  2. Сделайте переписывание в приложении.
  3. Используйте страшную директиву if.

There is also an option to use SNI, but I'm not sure this is fully supported as of now.

+0

Ваш простой код сделал трюк. Огромное спасибо! –

+0

Это решение обладает дополнительным преимуществом при отправке HTTP-кода с переадресацией на постоянный ответ HTTP 301. Это эффективное, элегантное и читаемое решение. Благодаря! – ndmeiri

Смежные вопросы