przekierowanie apache z non www na www

206

Mam witrynę, która nie wydaje się przekierowywać z innych niż www na www.

Moja konfiguracja Apache wygląda następująco:

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

czego mi brakuje?

użytkownik121196
źródło
1
W przypadku .htaccessrozwiązania opartego na propozycji sugeruję odpowiedź na pytanie o średnicy: stackoverflow.com/a/5262044/367456
hakre
to dobrze, ale dodaje ukośnika do adresu URL, więc stracić ukośnik przed dolarem.
wuxmedia

Odpowiedzi:

510

Korzystanie z silnika przepisywania jest dość ciężkim sposobem rozwiązania tego problemu. Oto prostsze rozwiązanie:

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

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

A potem będziesz mieć inną <VirtualHost>sekcję z ServerName www.example.comprawdziwą konfiguracją serwera. Apache automatycznie zachowuje wszystko po /użyciu Redirectdyrektywy , co jest powszechnym błędnym przekonaniem o tym, dlaczego ta metoda nie działa (kiedy w rzeczywistości działa).

Greg Hewgill
źródło
20
Jak to zrobić dla witryny, która ma również wirtualnego hosta ssl?
Shabbyrobe
28
Podczas korzystania z tej sugestii pojawia się błąd „Strona internetowa w example.com spowodowała zbyt wiele przekierowań”. Czy inni mają ten problem?
Jonathan Berger
4
@BlackDivine: Nie ma nic magicznego w robieniu tego w innym kierunku. Po prostu zamień www.examplei examplegdziekolwiek występują w próbce.
Greg Hewgill
11
@JonathanBerger Jeśli masz zbyt wiele przekierowań, prawdopodobnie plik nie został poprawnie skonfigurowany. Upewnij się, że masz 2 VirtualHosts: jeden z innymi niż www, co jest powyższe, a drugi z ServerName www.example.com, który ma prawdziwą konfigurację. Upewnij się również, że nie ma przekierowania w konfiguracji www.example.com (zarówno mod_alias, jak i mod_rewrite).
Savas Vedova,
3
W przypadku wirtualnego serwera hosta, powiedzmy example.com, mam, Redirect 301 / http://example2.com/extra/ale gdy przekierowuje, pomija ukośnik końcowy, co oznacza, że example.com/blahidzie do example2.com/extrablah. Jakieś pomysły? (Apache 2.2.22)
Peter Howe
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]
burzumko
źródło
3
bardzo krótka odpowiedź ... ale do rzeczy ... nie jestem pewien, czy to głos w górę, czy w dół
thecoshman
2
Och, to fajnie, można to uwzględnić w konfiguracji serwera na najwyższym poziomie (a jeśli tak, to dotyczy każdego wirtualnego hosta!
thenickdude
Witaj @burzumko, jak to osiągnąć, co jest prawdą dla wszystkich bez www, ale powiedzmy, przejdźmy example.com/subdi1/ws/* bez www?
czarny sensei
1
Użyłem tego rozwiązania również dla wirtualnych hostów HTTPS. Po prostu dodaj sdo http w trzecim rzędzie.
rodrigoap
46
<VirtualHost *:80>
    ServerAlias example.com
    RedirectMatch permanent ^/(.*) http://www.example.com/$1
</VirtualHost>
Cherouvim
źródło
To mi nie zadziałało; spowodowało nieskończoną pętlę przekierowania do tej samej strony
dmiller309
1
@ dmiller309: Czy zdarzy się, że zawarte www.w ServerAlias?
cherouvim
2
Masz rację, przypadkowo umieściłem www. w ServerAlias ​​za pomocą *. dzika karta. Ponieważ pomieszałem porządkowanie wpisów VirtualHost, *. wildcard miał okazję dopasować, kiedy nie sądziłem, że tak będzie.
dmiller309
7
To najlepsza odpowiedź, ponieważ jest czysta, zachowuje ścieżkę (w przeciwieństwie do odpowiedzi nr 1) i nie używa Rewrite.
schieferstapel
30

Aby usunąć wwwz URLwitryny, użyj tego kodu z .htaccesspliku:

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

Aby wymusić wwwna swojej stronie, URLużyj tego kodu na.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]

Gdzie YourSite.comnależy wymienić na swój URL.

kloddant
źródło
Najlepsza odpowiedź tutaj, ponieważ działa na stronie z wieloma nazwami domen <3
Clement Herreman
2
Jaka jest druga część z .html dla ??
Nathan H
6
Usuń ukośnik przed 1 $, aby nie miał podwójnego ukośnika (//) po przekierowaniu => RewriteRule ^ (. *) $ YourSite.com 1 $ [R = 301]
Kevin Campion
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>

Tak dzieje się z powyższym kodem. Pierwszy wirtualny blok hosta sprawdza, czy żądanie to www.example.com i uruchamia witrynę w tym katalogu.

W przeciwnym razie dochodzi do drugiej sekcji hosta wirtualnego. Tutaj wszystko inne niż www.example.com jest przekierowywane na www.example.com.

Kolejność tutaj ma znaczenie. Jeśli najpierw dodasz drugą dyrektywę virtualhost, spowoduje to pętlę przekierowania.

To rozwiązanie przekieruje każde żądanie do Twojej domeny, na www.twojadomena.com.

Twoje zdrowie!

Dishan Philips
źródło
16

Jest to podobne do wielu innych sugestii z kilkoma ulepszeniami:

  • Nie trzeba na stałe kodować domeny (działa z vhostami, które akceptują wiele domen lub między środowiskami)
  • Zachowuje schemat (http / https) i ignoruje skutki poprzednich %{REQUEST_URI}reguł.
  • Część ścieżki, na którą nie wpływają poprzednie RewriteRules, %{REQUEST_URI}to.

    RewriteCond %{HTTP_HOST} !^www\. [NC]
    RewriteRule ^(.*)$ %{REQUEST_SCHEME}://www.%{HTTP_HOST}/$1 [R=301,L]
    
weotch
źródło
4
Prawie idealnie. Musi to być% {HTTP_HOST} $ 1, a nie% {HTTP_HOST} / $ 1 (inaczej podwoi się)
Michael Wyraz
@Michael Wyraz: Nie podwoi cię tutaj ?!
not2savvy,
10
RewriteCond %{HTTP_HOST} ^!example.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]

Zaczyna się od HTTP_HOSTzmiennej, która zawiera tylko część nazwy domeny przychodzącego adresu URL ( example.com). Zakładając, że nazwa domeny nie zawiera a www.i dokładnie pasuje do nazwy domeny, wtedy zaczyna obowiązywać RewriteRule. Wzorzec ^(.*)$będzie pasował do wszystkiego REQUEST_URI, co jest zasobem wymaganym w żądaniu HTTP (foo/blah/index.html ). Przechowuje to w referencji wstecznej, która jest następnie używana do przepisania adresu URL nową nazwą domeny (taką, która zaczyna się odwww ).

[NC]wskazuje rozróżnianie wielkości liter bez rozróżniania wielkości liter, [R=301]wskazuje zewnętrzne przekierowanie za pomocą kodu 301 (zasób przeniesiony na stałe), [L]zatrzymuje wszelkie dalsze przepisywanie i natychmiast przekierowuje.

Curtis Tasker
źródło
6

Kod przekierowania zarówno dla strony innej niż www => www jak i przeciwnej www => non www. Brak domen i schematów na stałe w pliku .htaccess. Tak więc domena pochodzenia i wersja http / https zostaną zachowane.

PODAJ 2.4 i nowszy

NIE-WWW => WWW:

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

WWW => NIE-WWW:

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

Uwaga: nie działa na Apache 2.2, gdzie% {REQUEST_SCHEME} jest niedostępny. Aby zachować zgodność z Apache 2.2, użyj kodu poniżej lub zamień% {REQUEST_SCHEME} na stały http / https.


PODAJ 2.2 i nowszy

NIE-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]

... lub krótsza wersja ...

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 => NIE-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]

... krótsza wersja nie jest możliwa, ponieważ% N jest dostępny tylko z ostatniego RewriteCond ...

mikep
źródło
Konfiguracja Apache 2.4 naprawiła problem, dziękuję za czystą odpowiedź .. !!
KimchiMan,
5

Uruchomiłem to ...

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

Potrzebuję uniwersalności dla ponad 25 domen na naszym nowym serwerze, więc ta dyrektywa znajduje się w moim pliku virtual.conf w znaczniku <Directory>. (reż jest rodzicem wszystkich dokumentów)

Musiałem jednak trochę zhakować zasadę przepisywania, ponieważ pełny docroot został przeprowadzony podczas dopasowania wzorca, pomimo tego, co mówi http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html o tym, że to tylko rzeczy po hoście i porcie.

Andrew Deal
źródło
5

Jeśli używasz Apache 2.4, bez konieczności włączania modułu przepisywania Apache, możesz użyć czegoś takiego:

# non-www to www
<If "%{HTTP_HOST} = 'domain.com'">
  Redirect 301 "/" "http://www.domain.com/"
</If>
sys0dm1n
źródło
1
Niedoceniana odpowiedź. Dzięki temu można uniknąć dodatkowych vhostów, co jest dobre dla automatycznych skryptów Let'sEncrypt.
Paul
Dodatkowo, jeśli używasz ANSIBLE, od ANSIBLE 2.0 możesz teraz łatwo wstawić blok do pliku w jednym zadaniu, więcej szczegółów tutaj docs.ansible.com/ansible/2.5/modules/blockinfile_module.html
sys0dm1n
3

Przekieruj domain.tld na www.

Następujące linie można dodać w dyrektywach Apache lub w pliku .htaccess:

RewriteEngine on    
RewriteCond %{HTTP_HOST} .
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ http%{ENV:protossl}://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
  • Inne sudomains nadal działają.
  • Nie trzeba dostosowywać linii. po prostu skopiuj / wklej je we właściwym miejscu.

Nie zapomnij zastosować zmian w apache, jeśli zmodyfikujesz vhost.

(w oparciu o domyślny .htaccess Drupal7, ale powinien działać w wielu przypadkach)

xaa
źródło
3

To jest proste!

RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
kk4You
źródło
2
<VirtualHost *:80>
    ServerAlias example.com
    RedirectMatch permanent ^/(.*) http://www.example.com/$1
</VirtualHost>

To przekieruje nie tylko nazwę domeny, ale także wewnętrzne strony. Jak ...

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

Aneesh RS
źródło
Dzięki za to. Bardzo pomocne.
Anthony
2

Spróbuj tego:

RewriteEngine on
RewriteCond %{HTTP_HOST} ^example.com$ [NC]
RewriteRule ^(.*) http://www.example.com$1 [R=301]
Mark Ursino
źródło
2

Nie zawsze używaj Redirect permanent(lub dlaczego może to powodować problemy w przyszłości)

Jeśli istnieje szansa, że ​​dodasz subdomeny później, nie używaj redirect permanent.

Ponieważ jeśli klient użył subdomeny, która nie została zarejestrowana VirtualHost, może również nigdy nie dotrzeć do tej subdomeny, nawet jeśli zostanie ona później zarejestrowana.

redirect permanent wysyła HTTP 301 Moved Permanently do klienta (przeglądarkę) i wiele z nich buforuje tę odpowiedź na zawsze (dopóki pamięć podręczna nie zostanie wyczyszczona [ręcznie]). Dlatego użycie tej subdomeny zawsze spowoduje automatyczne przekierowanie na stronę www. *** bez ponownego żądania serwera.

zobacz Jak długo przeglądarki buforują HTTP 301?

Więc po prostu użyj Redirect

<VirtualHost *:80>
  ServerName example.com

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

Apache.org - Kiedy nie używać mod_rewrite

Apache.org - kanoniczne nazwy hostów

Martin Schneider
źródło
1

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

sprawdź tę idealną pracę

Tejinder singh
źródło
0

Mam tylko ten sam problem. Ale rozwiązany z tym

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

Ta reguła przekierowuje stronę inną niż www na www.

I ta reguła przekierowuje www na inne niż www

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

Patrz http://dense13.com/blog/2008/02/27/redirecting-non-www-to-www-with-htaccess/

Santo Doni Romadhoni
źródło
0

To działa dla mnie:

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

Używam wzorca (?!www.domain.com)przewidywania, aby wykluczyć wwwsubdomenę podczas przekierowywania wszystkich domen do wwwsubdomeny, aby uniknąć nieskończonej pętli przekierowań w Apache.

Mauricio Sánchez
źródło
0

Używam kodu:

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
użytkownik3597887
źródło
0

-Jeśli hostujesz wiele nazw domen (opcjonalnie)

-Jeśli wszystkie te nazwy domen używają https (tak jak powinny)

-jeśli chcesz, aby wszystkie te nazwy domen używały www krop nazwa_domeny

Pozwoli to uniknąć przekierowania podwójnego (http: // non www do http: // www, a następnie do https: // www)

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

I

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

Powinieneś zmienić kod przekierowania 301 na najwygodniejszy

JOGO
źródło
-1

Jeśli używasz powyższego rozwiązania dwóch <VirtualHost *:80>bloków o różnych ServerNames ...

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

... wtedy należy ustawić NameVirtualHost Ontak dobrze .

Jeśli tego nie zrobisz, Apache nie pozwoli sobie na użycie różnych ServerNames do rozróżnienia bloków, więc pojawia się następujący komunikat o błędzie:

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

... i albo nie następuje przekierowanie, albo masz nieskończoną pętlę przekierowania, w zależności od tego, który blok umieścisz jako pierwszy.

Stuart Caie
źródło
-1

Miałem podobne zadanie na WP Multisite, gdzie reguła przekierowywania musiała być ogólna (dla dowolnej domeny, którą dodałbym do sieci). Rozwiązałem najpierw dodając symbol wieloznaczny do domeny (zaparkowana domena). Zanotuj . po .com.

CNAME * domain.com.

A potem dodałem następujące wiersze do pliku .htaccess w katalogu głównym mojej witryny. Myślę, że to zadziałałoby na każdej stronie.

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

Mam nadzieję, że to pomoże.

ps. Jeśli chcesz przekierować z nie www na www, zmień ostatni wiersz na

RewriteRule ^(.*)$ http://www.%1/$1 [R=301,L]
Carlo Rizzante
źródło
-2

Uznałem, że łatwiej (i bardziej użyteczne) jest używanie ServerAlias ​​podczas korzystania z wielu vhostów.

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

Działa to również z vhostami https.

Fabian76
źródło
Kolejny głos negatywny. Chcesz wyjaśnić, oh, potężny bóg httpd, który nie mógłby zadać sobie trudu, aby wyjaśnić opinię negatywną?
Anthony
1
Dzięki temu masz wiele domen hostujących tę samą witrynę. W zależności od sytuacji i tego, na czym działa podstawowy serwer internetowy, będziesz mieć problemy z nieprzenoszeniem plików cookie, ludźmi zdezorientowanymi i problemami z wyszukiwarkami (które będą postrzegane jako 2 różne witryny).
Jeffrey Van Alstine