Nginx переписывает домен без префикса www в домен с префиксом www

StackOverflow https://stackoverflow.com/questions/1629231

  •  06-07-2019
  •  | 
  •  

Вопрос

Я вижу, что у документации HttpRewriteModule есть пример переписать домен с префиксом 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 в домен с префиксом 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 и т. д., так как мне нужно переписать большое количество доменов.

Это было полезно?

Решение 3

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

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

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

Другие советы

Как отмечено в документации по Nginx, вам следует избегать использования < директива code> if в Nginx, где это возможно , потому что, как только в вашей конфигурации есть 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), у вас есть более или менее три разных варианта.

<Ол>
  • Настройте несколько IP-адресов, чтобы каждая серверная директива прослушивала свой собственный IP (или разные порты, если это вариант для вас). Для этого варианта требуются сертификаты SSL как для website.com , так и для www.website.com , поэтому у вас есть сертификат подстановочного знака, сертификат UNI (несколько доменов) или просто два разных сертификата.
  • Сделайте переписывание в приложении.
  • Используйте страшную директиву if .
  • Также есть возможность использовать SNI, но я не уверен в этом на данный момент полностью поддерживается .

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

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

    Документация nginx предостерегает от использования if для перезаписи. Смотрите ссылку здесь: http://wiki.nginx.org/Pitfalls#Server_Name

    HTTP & amp; HTTPS без условий if:

    server {
        listen          80;
        listen          443;
        server_name     website.com;
    
        return 301 $scheme://www.website.com$request_uri;
    }
    server {
        listen          80;
        listen          443 default_server ssl;
        server_name     www.website.com;
    
        # Your config goes here #
    }
    
    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top