Apache перенаправить с не www на www

159

У меня есть веб-сайт, который, похоже, не перенаправляется с не-www на www.

Моя конфигурация Apache выглядит следующим образом:

RewriteEngine On
### re-direct to www
RewriteCond %{http_host} !^www.example.com [nc]
RewriteRule ^(.*)$ http://www.example.com/$1 [r=301,nc] 

Что мне не хватает?

  • 1
    Для решения на основе .htaccess я предлагаю ответ, который был поставлен на диаметральный вопрос: stackoverflow.com/a/5262044/367456
Теги:
redirect
mod-rewrite
no-www

21 ответ

435
Лучший ответ

Использование механизма перезаписи - довольно тяжелый способ решить эту проблему. Вот более простое решение:

<VirtualHost *:80>
    ServerName example.com
    Redirect permanent / http://www.example.com/
</VirtualHost>

<VirtualHost *:80>
    ServerName www.example.com
    # real server configuration
</VirtualHost>

И тогда у вас будет другой раздел <VirtualHost> с ServerName www.example.com для вашей реальной конфигурации сервера. Apache автоматически сохраняет что-либо после / при использовании директивы Redirect, которая является распространенным заблуждением о том, почему этот метод не будет работать (когда это действительно так).

  • 14
    Как вы делаете это для сайта, который также имеет виртуальный хост ssl?
  • 28
    Я получаю сообщение об ошибке "Веб-страница на example.com привела к слишком большому количеству перенаправлений" при использовании этого предложения. У других есть эта проблема?
Показать ещё 27 комментариев
55

http://example.com/subdir/?lold=13666 = > http://www.example.com/subdir/?lold=13666

    RewriteEngine On
    RewriteCond %{HTTP_HOST} !^www\. [NC]
    RewriteRule ^(.*)$ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
  • 3
    очень короткий ответ ... но по пунктам ... не уверен, если это голосование "за" или "против"
  • 2
    О, это здорово, это может быть включено в конфигурацию сервера на верхнем уровне (и если так) будет применяться к каждому виртуальному хосту!
Показать ещё 2 комментария
39
<VirtualHost *:80>
    ServerAlias example.com
    RedirectMatch permanent ^/(.*) http://www.example.com/$1
</VirtualHost>
  • 0
    Это не сработало для меня; это вызвало бесконечный цикл перенаправления на тот же сайт
  • 1
    @ dmiller309: Вы случайно включили www. в ServerAlias ?
Показать ещё 2 комментария
29

Чтобы удалить www с вашего веб-сайта URL, используйте этот код в файле .htaccess:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http://%1$1 [R=301,L]

Чтобы заставить www на вашем веб-сайте URL использовать этот код на .htaccess

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^YourSite.com$
RewriteRule ^(.*)$ http://www.yourSite.com/$1 [R=301]
RewriteCond %{REQUEST_fileNAME} !-d
RewriteCond %{REQUEST_fileNAME} !-f
RewriteRule ^(([^/]+/)*[^./]+)$ /$1.html [R=301,L]

Где YourSite.com необходимо заменить на URL.

  • 0
    Лучший ответ здесь, так как он работает для веб-сайта с несколькими доменными именами <3
  • 2
    Какова вторая часть с .html для ??
Показать ещё 2 комментария
19
    <VirtualHost *:80>
       DocumentRoot "what/ever/root/to/source"
       ServerName www.example.com

       <Directory "what/ever/root/to/source">
         Options FollowSymLinks MultiViews Includes ExecCGI
         AllowOverride All
         Order allow,deny
         allow from all
         <What Ever Rules You Need.>
      </Directory>

    </VirtualHost>

    <VirtualHost *:80>
      ServerName example.com
      ServerAlias *.example.com
      Redirect permanent / http://www.example.com/
    </VirtualHost>

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

В противном случае это относится ко второй секции виртуального хоста. Здесь ничего, кроме www.example.com, перенаправляется на www.example.com.

Здесь порядок. Если вы сначала добавите вторую директиву virtualhost, это вызовет цикл перенаправления.

Это решение перенаправит любой запрос в ваш домен, на www.yourdomain.com.

Ура!

11

Это похоже на многие другие предложения с несколькими улучшениями:

  • Не нужно жестко кодировать домен (работает с vhosts, которые принимают несколько доменов или между средами)
  • Сохраняет схему (http/https) и игнорирует эффекты предыдущих %{REQUEST_URI} правил.
  • Часть пути, на которую не влияет предыдущий RewriteRule, такой как %{REQUEST_URI}.

    RewriteCond %{HTTP_HOST} !^www\. [NC]
    RewriteRule ^(.*)$ %{REQUEST_SCHEME}://www.%{HTTP_HOST}/$1 [R=301,L]
    
  • 4
    Практически идеально. Это должно быть% {HTTP_HOST} $ 1, а не% {HTTP_HOST} / $ 1 (или это удвоит косую черту)
  • 0
    @ Майкл Вираз: не удваивает слэш здесь ?!
9
RewriteCond %{HTTP_HOST} ^!example.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]

Это начинается с переменной HTTP_HOST, которая содержит только часть имени домена входящего URL (example.com). Предполагая, что доменное имя не содержит www. и точно соответствует вашему доменному имени, тогда вступает в действие RewriteRule. Шаблон ^(.*)$ будет соответствовать всем в REQUEST_URI, который является ресурсом, запрошенным в HTTP-запросе (foo/blah/index.html). Он хранит это в обратной ссылке, которая затем используется для перезаписи URL-адреса с новым доменным именем (которое начинается с www).

[NC] указывает на совпадение шаблонов с учетом регистра, [R=301] указывает внешнюю переадресацию с использованием кода 301 (ресурс перемещается постоянно), а [L] останавливает дальнейшую переписывание и немедленно перенаправляет.

5

Я запустил это...

 RewriteEngine on
 RewriteCond %{HTTP_HOST} !^www.*$ [NC]
 RewriteRule ^/.+www\/(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]

Мне нужно, чтобы это было универсальным для 25+ доменов на нашем новом сервере, поэтому эта директива находится в моем файле virtual.conf в теге Directory > . (dir является родительским для всех docroots)

Мне пришлось немного взломать правило перезаписи, поскольку полный docroot переносился на совпадение шаблонов, несмотря на то, что http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html говорит об этом только о вещах после хоста и порта.

3

Перенаправить domain.tld на www.

Следующие строки могут быть добавлены либо в директивы Apache, либо в файле .htaccess:

RewriteEngine on    
RewriteCond %{HTTP_HOST} .
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ http%{ENV:protossl}://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
  • Другие судомены все еще работают.
  • Не нужно настраивать линии. просто скопируйте/вставьте их в нужное место.

Не забывайте применять изменения apache, если вы изменяете vhost.

(основанный на стандартном Drupal7.htaccess, но должен работать во многих случаях)

2

Код перенаправления для не-www = > www и напротив www = > не-www. Никаких доменов и схем жесткого кодирования в файле .htaccess. Таким образом, исходный домен и версия http/https будут сохранены.

APACHE 2.4 И NEWER

NON-WWW = > WWW:

RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ %{REQUEST_SCHEME}://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

WWW = > NON-WWW:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^ %{REQUEST_SCHEME}://%1%{REQUEST_URI} [R=301,L]

Примечание: не работает на Apache 2.2, где% {REQUEST_SCHEME} недоступен. Для совместимости с Apache 2.2 используйте код ниже или замените% {REQUEST_SCHEME} на фиксированный http/https.


APACHE 2.2 И NEWER

NON-WWW = > WWW:

RewriteEngine On

RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

... или более короткая версия...

RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS}s ^on(s)|offs
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

WWW = > NON-WWW:

RewriteEngine On

RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]

RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]

... более короткая версия невозможна, потому что% N доступен только из последнего RewriteCond...

2

Если вы используете Apache 2.4, без необходимости включения переписанного модуля apache, вы можете использовать что-то вроде этого:

# non-www to www
<If "%{HTTP_HOST} = 'domain.com'">
  Redirect 301 "/" "http://www.domain.com/"
</If>
2
<VirtualHost *:80>
    ServerAlias example.com
    RedirectMatch permanent ^/(.*) http://www.example.com/$1
</VirtualHost>

Это приведет к перенаправлению не только имени домена, но и внутреннего  pages.like...

 example.com/abcd.html             == >      ; www.example.com/abcd.html
example.com/ab/cd.html?ef=gh   == >   www.example.com/ab/cd.html?ef=gh

  • 0
    Спасибо за это. Очень полезно.
  • 0
    Добро пожаловать :)
1

Не всегда используйте Redirect permanent (или почему это может вызвать проблемы)

Если есть вероятность, что позже вы добавите субдомены, не используйте Redirect permanent.

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

Redirect permanent отправляет HTTP 301 Moved Permanently клиенту (браузеру), и многие из них кэшируют этот ответ навсегда (пока кеш не будет очищен [вручную]). Таким образом, использование этого поддомена будет всегда авторизоваться на www. *** без повторного запроса сервера.

см. Как долго браузеры кэшируют HTTP 301?

Так что просто используйте Redirect

<VirtualHost *:80>
  ServerName example.com

  Redirect / http://www.example.com/
</VirtualHost>

Apache.org - Когда не использовать mod_rewrite

Apache.org - Канонические имена хостов

1

RewriteEngine On RewriteCond %{HTTP_HOST} ^yourdomain.com [NC] RewriteRule ^(.*)$ http://www.yourdomain.com/$1 [L,R=301]

проверить эту прекрасную работу

1

Попробуйте следующее:

RewriteEngine on
RewriteCond %{HTTP_HOST} ^example.com$ [NC]
RewriteRule ^(.*) http://www.example.com$1 [R=301]
0

Это работает для меня:

RewriteCond %{HTTP_HOST} ^(?!www.domain.com).*$ [NC]
RewriteRule ^(.*)$  http://www.domain.com$1  [R=301,L]

Я использую шаблон с перспективой (?!www.domain.com), чтобы исключить субдомен www при перенаправлении всех доменов в субдомен www, чтобы избежать бесконечного цикла перенаправления в Apache.

0

У меня только одна проблема. Но решил с этим

RewriteEngine On RewriteCond %{HTTP_HOST} !^www\. RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]

Это правило перенаправляет не-www на www.

И это правило для перенаправления www на не-www

RewriteEngine On RewriteCond %{HTTP_HOST} !^my-domain\.com$ [NC] RewriteRule ^(.*)$ http://my-domain.com/$1 [R=301,L]

Обратитесь к http://dense13.com/blog/2008/02/27/redirecting-non-www-to-www-with-htaccess/

0

Используемый мной код:

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
0

Если вы используете вышеупомянутое решение из двух блоков <VirtualHost *:80> с разными ServerName s...

<VirtualHost *:80>
    ServerName example.com
    Redirect permanent / http://www.example.com/
</VirtualHost>
<VirtualHost *:80>
    ServerName www.example.com
</VirtualHost>

... тогда вы должны также установить NameVirtualHost On.

Если вы этого не сделаете, Apache не позволяет использовать разные ServerName для выделения блоков, поэтому вы получите это сообщение об ошибке:

[warn] _default_ VirtualHost overlap on port 80, the first has precedence

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

-2

У меня была аналогичная задача в WP Multisite, где правило перенаправления должно было быть общим (для любого заданного домена, который я бы добавил в сеть). Сначала я решил добавить подстановочный знак в домен (припаркованный домен). Обратите внимание. после .com.

CNAME * domain.com.

И затем я добавил следующие строки в файл .htaccess в корень моего мультисайта. Думаю, это сработает для любого сайта.

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

Надеюсь, это поможет.

пс. Если вы хотите перенаправить с www на www, измените последнюю строку на

RewriteRule ^(.*)$ http://www.%1/$1 [R=301,L]
-2

Мне было проще (и более полезно) использовать ServerAlias ​​при использовании нескольких vhosts.

<VirtualHost x.x.x.x:80>
    ServerName www.example.com
    ServerAlias example.com
    ....
</VirtualHost>

Это также работает с https vhosts.

  • 0
    Очередной проезд вниз. Не могли бы вы объяснить, о могущественный бог httpd, который не удосужился объяснить понижение?
  • 1
    Это позволяет вам иметь несколько доменов, на которых размещается один и тот же сайт. В зависимости от ваших ситуаций и от того, что работает ваш базовый веб-сервер, у вас могут возникнуть проблемы с тем, что файлы cookie не будут перенесены, люди в замешательстве и проблемы с поисковой системой (которые будут отображаться как 2 разных сайта).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню