14 сентября 2008 в 17:33

Организация постоянных редиректов с www.domain на domain и обратно.

Так исторически сложилось, что домены сайтов называют с префиксом www или без.

Есть несколько взглядов как истинно должен называться домен, прогрессивное человечество считает, что без www — nowww.ru, многие западные эксперты считают обратное.

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

В первую очередь нужно сказать, что редирект должен быть постоянным, т.е. отдавать код ответа 301 Moved Permanently для того, чтобы браузеры не запоминали url, с котрого был произведен редирект.

Общий принцип такой:
* описываем сервер с именем сервера, с которого делаем редирект
* указываем директиву для редиректа

Apache 2.2, 2.0, 1.3, RedirectMatch из mod_alias, тоже самое можно сделать при помощи mod_rewrite:
<VirtualHost *:80>
  ServerName              example.com:80
  RedirectMatch permanent (.*) http://www.example.com$1
</VirtualHost>


Nginx, rewrite из http_rewrite_module:
server {
  server_name example.com;
  rewrite ^(.*)$ http://www.example.com$1 permanent;
}



Дабы не указывать это правило для каждого домена можно воспользоваться отрицательным регулярным выражением:

server {
  server_name ~^(?! www\.);
  rewrite ^ http://www.$host$request_uri permanent;
}


При этом явно описанные сайты без www сюда уже не попадут — regex'ы
в server_name используются как last resort.

Автор решения Игорь Сысоев.

Будет здорово, если мы перечислим способы организации постоянных редиректов для других популярных web серверов.

UPD: добавлена заметка об общем редиректе для nginx
Timur Vafin @timurv
карма
33,6
рейтинг 0,0
Похожие публикации
Самое читаемое Администрирование

Комментарии (59)

  • +2
    поправьте заголовок «Организайия»
    • 0
      и раз уж вы считаете что здорово бы указать и про другие веб сервера, то может расскажите про IIS 7.0? было бы интересно
      • +1
        К сожалению ни разу не видел IIS. Могу предложить только такую информацию с www.webconfs.com/how-to-redirect-a-webpage.php

        * In internet services manager, right click on the file or folder you wish to redirect
        * Select the radio titled «a redirection to a URL».
        * Enter the redirection page
        * Check «The exact url entered above» and the «A permanent redirection for this resource»
        * Click on 'Apply'

        Надеюсь меня поправят, и предложат более детальный вариант

        • +3
          Под IIS есть ISAPI фильтр поддерживающий RewriteRules в стиле mod_rewtite
          • +1
            За что минусуем, гении IIS-а?
    • 0
      Спасибо, исправил.
  • 0
    Какую задачу выполняет этот редирект?
    Что плохого в том, что сайт открывается с www и без www?
    • +2
      В принципе ничего плохого нет, однако есть некторые неприятные моменты связанные с тем, что сайт будет выдаваться в выдаче поисковиков по двум разным доменам:
      * adsens * adwords рекламу необходимо давать для одного конкретного домена, чтобы потом было удобвно отслеживать статистику.
      • +1
        В серпе два разных домена очень быстро склеятся в какой-то один.
    • +8
      Главная проблема — с куками. В большом количестве разного рода пакетов вы должны прописать домен, на котором этот пакет работает. При этом очень легко добиться того, чтобы читатель попал на форму регистрации на одном домене, ввёл имя-пароль, его перебросили на другой домен — и там заявили что, дескать «не знаем мы вас».

      Если ваша система (как Хабрахабр) реально пользуется многими доменами, то приходится заботится о правильной работе всего этого хозяйства, но если сайт невелик — то удобнее перебрасывать на один домен, а если велик, то нужно перебрасывать на один домен причём этот домент обязательно должен включать в себя пресловутое www. Это, опять-таки, связано с куками: никакого untrustedsubproject.habrahabr.ru в природе быть не может ибо этот untrustedsubproject будет получать конфиденциальную информацию о всех посетителях habrahabr.ru!
      • 0
        Спасибо!

        то то я смотрю при наборе www.habrahabr.ru идёт редирект на habrahabr.ru и в заголовках:
        HTTP/1.x 302 Moved Temporarily
        Location: habrahabr.ru/
        • 0
          хм… должен же быть 301
  • +1
    А зачем rewrite? Просто алиасом поднимать домен с www и все будут довольны.
    • 0
      Задача в том, чтобы сделать редирект.
    • 0
      См. выше. Alias в очень многих случаях не годится.
    • 0
      будут проблемы с куками, домен может двоиться в поисковиках (из-за чего рейтинг будет меньше чем мог бы)
  • +4
    Через .htaccess:
    RewriteEngine on
    RewriteCond %{SERVER_NAME} ^example.com
    RewriteRule (.*) www.example.com/$1 [QSA, L, R=301]
    • +4
      Парсер ест код:
      RewriteEngine on
      RewriteCond %{SERVER_NAME} ^example.com
      RewriteRule (.*) www.example.com/$1 [QSA, L, R=301]
      • +1
        Всё равно ест. Короче, перед www.example.com в последней строчке должен протокол (хттп://)
        • 0
          RewriteEngine on
          RewriteCond %{SERVER_NAME} ^example.com
          RewriteRule (.*) http://www.example.com/$1 [QSA, L, R=301]
          :)
          • 0
            А как? Я заменял на html-entities разные части адреса, и в предпросмотре оно показывалось как надо. А вот после отправки код ломался.

            Кстати, в последней части после запятых не должно быть пробелов. Хабрапарсер явно чудит, я бы даже сказал слишком.
        • 0
          Попробуйте использовать для кода элемент code («код») вместо blockquote («цитата»):http://www.example.com
          • 0
            У меня почему-то он, по крайней мере в предпросмотре, при использовании этого тега игнорирует переносы строк и выдаёт всё одной строкой, что определённо ещё хуже.
  • –15
    Сайт должен иметь www., потому что это хорошая стандартизация.

    А те, кто на «без www.» редиректят — дети, которые не в курсе что кроме www есть другие протоколы.

    Кроме того при указании адреса в прессе лучше использовать www, так как это намного понятнее.
    • +16
      Ну если «кроме www есть другие протоколы» то конечно да
    • +3
      Простите, а когда «www» стал протоколом? :)
    • +1
      видимо автор попутал www с http
    • –3
      Если субдомен (test.example.com), то www не пишу. Иначе пишу всегда с www (www.example.com) — так как-то приятнее… ИМО
      • 0
        emo?
    • 0
      www — не протокол…
    • 0
      Я бы не стал так котигорично минусовать автора этого коммента.

      Да… www не протокол.
      Но www достаточно прочно вошло в сознание многих «домохозяек» именно как ассоциация с адресом сайта.
      Так же как @ как ассоциация с e-mail.
      • –3
        Да и хрен с ними.

        Собрались тут 500 пионеров и дрочат друг друга за плюсики вместо того, чтобы делом заняться.: о))
  • +1
    Несколько раз сталкивался невероятным: админ заказчика тупо не знает что MX-записи могут на другой сервер указывать, поэтому у них разные IP-адреса у корневого домена и www.
    • +6
      Пятый(?) год уже прекрасные люди из Мегафона немогут\не хотят устроить альясинг или реврайт
      megafonnw.ru/ — не работает, в отличие от
      www.megafonnw.ru/
      • +1
        НЕ СМЕЙТЕ ДАВИТЬ НА НАС!

        :)
        • 0
          Кто здесь?
      • +2
        ещё примеры из серии:
        www.ibc.org/ крупная выставка плотно связанная с IT
        www.wymeditor.org/ WYSIWYM редактор
        где то видел ещё но так не вспомню. очень обидно когда набираешь адрес по памяти и не можешь зайти, создаеться впечатление что сайт мертв…
    • 0
      A-записи наверно имели в виду.
      • 0
        Да какая разница, главное, что они друг от друга не зависят.
  • 0
    Кстати, вы бы кстати ещё и немножко про SEO упомянули бы. И как разные поисковики реагируют на 301-й редирект, и как учесть все особенности.
  • 0
    Еще один вариант с htaccess-ом, аналогичный TiGR:

    # BEGIN redirect settings <IfModule mod_rewrite.c> RewriteCond %{HTTP_HOST} !www.example.ru RewriteRule ^.*$ http://www.example.ru%{REQUEST_URI} [R,L] </IfModule> # END redirect settings отличается большей гибкостью, т.к. при наборе example.ru/coollink редиректит на www.exmple/coollink
    • 0
      прошу прощения, код получился, но не получилась разметка, второй раз пробовать не буду, а поставлю костыль к своему комменту:

      новые строки начинаются с:

      RewriteCond
  • +1
    сразу видно менеджер проектов: не только с кодом не дружу, даже всивиг не дается +)

    IfModule
    RewriteCond
    RewriteRule
    /IfModule
  • 0
    Поправьте меня, если я ошибаюсь — а не проще ли просто использовать ServerAlias в описании VirtualHost'а и не городить редиректы?
  • +1
    Дабы не указывать это правило для каждого домена можно воспользоваться отрицательным регулярным выражением:

    server { server_name ^(?!www\.); rewrite ^ http://www.$host$request_uri permanent; }

    При этом явно описанные сайты без www сюда уже не попадут — regex'ы
    в server_name используются как last resort.

    Автор решения Игорь Сысоев. Советую автору вынести это в содержание топика.
    • 0
      Забыл сказать, что решение для nginx
    • 0
      Ошибочка:

      — server_name ^(?! www\.);
      + server_name ~^(?! www\.);

      Хабрапарсер, перед www не надо пробела.
    • 0
      Спасибо, так и сделаю.
    • 0
      А наоборот? www.example.com -> example.com
      • 0
        Я сделал так:

        server {
        server_name ~^(?=www\.);
        if ( $host ~* "www.(.*)"){
        set $unwww $1;
        }
        rewrite ^ $scheme://$unwww$request_uri permanent;
        }


        вставляется в начало блока http файла nginx.xonf и не забываем убирать в конфах вирт. серваков из server_name вариант с www., а то не сработает
        • +1
          Вариант без условий (if советуют избегать)
          server {
            server_name ~^www\.(?<domain>.+)$;
            rewrite ^ $scheme://$domain$request_uri permanent;
          }
          
          • 0
            Непонятно почему, но с punycode этот вариант работает некорректно, переадресация идет на
            http:///
            
  • +1
    Вы забыли здесь
    RedirectMatch permanent (.*) www.example.com$1
    поставить http://
    RedirectMatch permanent (.*) http://www.example.com$1
    Поэтому апач редиректит на
    example.com/www.example.com$1
    • 0
      Спасибо, не заметил как habr съел.
  • 0
  • 0
    if ($host != 'example.com') {
    rewrite ^/(.*)$ example.com/$1 permanent;
    }
    в секции server будет переадресовывать пользователей с любого поддомен на домен example.com. Если требуется организовать переадресацию исключительно www.example.com → example.com использовать можно следующую конструкцию:
    if ($host = 'www.example.com') {
    rewrite ^/(.*)$ example.com/$1 permanent;
    }
  • 0
    В апаче есть просто Redirect (без регэкспа)

        ServerName www.example.com
        Redirect permanent / http://example.com/
    
    • 0
      Вы сможете сделать при помощи `Redirect` «умное» перенаправление типа example.com/some-url на www.example.com/some-url?
      • 0
        Именно так оно и делается, на нескольких сотнях сайтов под моим присмотром.

        httpd.apache.org/docs/2.2/mod/mod_alias.html#redirect

        «Additional path information beyond the matched URL-path will be appended to the target URL.»

        RTFM хоть иногда

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.