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


206

У меня есть веб-сайт, который не перенаправляет с не-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
Хакре,

это хорошо, хотя это добавляет косую черту к URL, поэтому потеряйте косую черту перед долларом.
wuxmedia

Ответы:


510

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

<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директивы , что является распространенным заблуждением о том, почему этот метод не работает (хотя на самом деле он работает).


20
Как вы делаете это для сайта, который также имеет виртуальный хост ssl?
Шаббироб

28
Я получаю сообщение об ошибке "Веб-страница на example.com привела к слишком большому количеству перенаправлений" при использовании этого предложения. У других есть эта проблема?
Джонатан Бергер

4
@ BlackDivine: нет ничего волшебного в том, чтобы делать это в другом направлении. Просто поменяйте местами www.exampleи exampleвезде, где они появляются в образце.
Грег Хьюгилл

11
@JonathanBerger Если у вас слишком много перенаправлений, значит, вы, вероятно, неправильно настроили файл. Убедитесь, что у вас есть 2 виртуальных хоста: один с не-www, как указано выше, а другой с ServerName www.example.com, который имеет реальную конфигурацию. Также убедитесь, что у вас нет переадресации в конфигурации www.example.com (как mod_alias, так и mod_rewrite).
Савас Ведова

3
Для сервера виртуального хоста, скажем, example.com, у меня есть, Redirect 301 / http://example2.com/extra/но когда он перенаправляет, он пропускает завершающий слеш, что означает, что example.com/blahидет example2.com/extrablah. Любые идеи? (Apache 2.2.22)
Питер Хоу

88

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
очень короткий ответ ... но по пунктам ... не уверен, если это голосование "за" или "против"
thecoshman

2
О, это здорово, это может быть включено в конфигурацию сервера на верхнем уровне (и если так) будет применяться к каждому виртуальному хосту!
thenickdude

Здравствуйте @burzumko, как вы этого добиваетесь, что верно для всех без www, но затем позвольте, скажем, example.com/subdi1/ws/* пройти без www?
черный сенсей

1
Я использовал это решение и для виртуальных хостов HTTPS. Просто добавьте sк http в третьем ряду.
Родригоап

46
<VirtualHost *:80>
    ServerAlias example.com
    RedirectMatch permanent ^/(.*) http://www.example.com/$1
</VirtualHost>

Это не сработало для меня; это вызвало бесконечный цикл перенаправления на один и тот же сайт
dmiller309

1
@ dmiller309: Вы случайно включили www.в ServerAlias?
Черувим

2
Вы правы, я случайно поставил www. в ServerAlias ​​используя *. подстановочные. Поскольку я испортил порядок записей VirtualHost, *. У подстановочного знака была возможность соответствовать, когда я не думал, что это будет.
dmiller309

7
Это лучший ответ, потому что он чистый, сохраняет путь (в отличие от ответа № 1) и не использует перезапись.
schieferstapel

30

Чтобы удалить 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.


Лучший ответ здесь, так как он работает для веб-сайта с несколькими доменными именами <3
Clement Herreman

2
Какова вторая часть с .html для ??
Натан Х

6
Удалите косую черту до $ 1, чтобы после перенаправления не было двойной косой черты (//) => RewriteRule ^ (. *) $ YourSite.com $ 1 [R = 301]
Кевин Кэмпион

22
    <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.

Ура!


16

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

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

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

4
Практически идеально. Это должно быть% {HTTP_HOST} $ 1, а не% {HTTP_HOST} / $ 1 (или это удвоит косую черту)
Майкл Вираз

@ Майкл Вираз: не удваивает слэш здесь ?!
not2savvy

10
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]останавливает все дальнейшее переписывание и немедленно перенаправляет.


6

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

APACHE 2.4 и новее

NON-WWW => WWW:

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

WWW => НЕ 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 и новее

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 => НЕ 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 ...


Конфиг Apache 2.4 исправил проблему, спасибо за чистый ответ .. !!
KimchiMan

5

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

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

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

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


5

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

# non-www to www
<If "%{HTTP_HOST} = 'domain.com'">
  Redirect 301 "/" "http://www.domain.com/"
</If>

1
Недооцененный ответ. Используя это, можно избежать дополнительных vhosts, что хорошо для автоматизированных скриптов Let'sEncrypt.
Пол

Кроме того, если вы используете ANSIBLE, то, начиная с ANSIBLE 2.0, вы теперь можете легко вставить блок в файл в одной задаче, более подробную информацию можно найти
sys0dm1n

3

Перенаправить домен .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]
  • Другие sudomains все еще работают.
  • Не нужно настраивать линии. просто скопируйте / вставьте их в нужном месте.

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

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


3

Это просто!

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

2
<VirtualHost *:80>
    ServerAlias example.com
    RedirectMatch permanent ^/(.*) http://www.example.com/$1
</VirtualHost>

Это перенаправит не только доменное имя, но и внутренние страницы. Как ...

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


Спасибо за это. Очень полезно.
Энтони


2

Не всегда используйте 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

-Если вы размещаете несколько доменных имен (необязательно)

-Если все эти доменные имена используют https (как они должны)

-Если вы хотите, чтобы все эти доменные имена использовали www точка domainName

Это позволит избежать двунаправленного перенаправления (с http: // non www на http: // www, а затем на https: // www)

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

И

<VirtualHost *:443>
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}$1 [R=301,L]
</VirtualHost>

Вы должны изменить код перенаправления 301 на наиболее удобный


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

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

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
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

-1

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

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

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

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

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

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


-1

У меня была похожая задача на 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.


Еще один проезд вниз. Не могли бы вы объяснить, о могущественный бог httpd, который не удосужился объяснить понижение?
Энтони

1
Это позволяет вам иметь несколько доменов, на которых размещается один и тот же сайт. В зависимости от вашей ситуации и от того, что работает ваш основной веб-сервер, у вас могут возникнуть проблемы с тем, что файлы cookie не будут перенесены, люди в замешательстве и проблемы с поисковой системой (которые будут отображаться как 2 разных сайта).
Джеффри Ван Алстайн
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.