перенаправлення 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
hakre

це добре, але це додає нахилу до 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 VirtualHosts: один з не-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)
Пітер Хоу

87

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. Просто додайте shttp у третьому ряду.
rodrigoap

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

Це не спрацювало для мене; це спричинило нескінченну петлю переадресації на той самий сайт
dmiller309

1
@ dmiller309: Чи трапляється ви, що ви ввійшли www.до складу ServerAlias?
cherouvim

2
Ви маєте рацію, я випадково поставив www. в ServerAlias ​​за допомогою *. wildcard. Оскільки я зіпсував впорядкування записів VirtualHost, *. wildcard мав можливість збігатися, коли я не думав, що це станеться.
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
Клемент Герреман

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}правил.
  • Частина шляху, на яку не впливали попередні RewriteRules, %{REQUEST_URI}є.

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

4
Майже ідеально. Це має бути% {HTTP_HOST} $ 1, а не% {HTTP_HOST} / $ 1 (або це подвоїть косу
рису

@Michael Wyraz: Не подвоїть косу рису ?!
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 => non-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 => 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 І НОВІ

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


Apache 2.4 config виправив проблему, дякую за чітку відповідь .. !!
KimchiMan

5

Я керував цим ...

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

Мені потрібно, щоб це було універсальним для 25+ доменів на нашому новому сервері, тому ця директива знаходиться у моєму файлі virtual.conf у тезі <Directory>. (реж. є батьком для всіх docroots)

Мені довелося трохи зламати правило перезапису, хоча повний docroot переносився на відповідність шаблону, незважаючи на те, що говорить 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, що добре для автоматизованих скриптів LetEncrypt.
Павло

Крім того, якщо ви використовуєте ANSIBLE, оскільки ANSIBLE 2.0 тепер ви можете легко вставити блок у файл в одному завданні, детальніше тут docs.ansible.com/ansible/2.5/modules/blockinfile_module.html
sys0dm1n

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 за замовчуванням, але повинен працювати у багатьох випадках)


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

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

перевірити цю ідеальну роботу


0

У мене просто така ж проблема. Але вирішено з цим

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

Це правило перенаправляє non-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

-Якщо ви розміщуєте кілька імен домену (необов’язково)

-Якщо всі ці доменні імена використовують https (як слід)

-якщо ви хочете, щоб усі ці доменні імена використовували www dot domainName

Це дозволить уникнути можливого перенаправлення (http: // non www to 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 на найзручніший


-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, які не переносяться, людьми плутаються проблеми та пошуковими системами (які будуть розглядатись як два різних сайти).
Джеффрі Ван Альстін
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.