htaccess przekierowuje na https: // www


309

Mam następujący kod htaccess:

<IfModule mod_rewrite.c>

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

</IfModule>

Chcę, aby moja witryna została przekierowana za https://www.pomocą HTTPS i wymusiła www.poddomenę, ale kiedy uzyskuję dostęp http://www.(bez HTTPS), nie przekierowuje mnie do niej za https://wwwpomocą HTTPS.


Powinien byćRewriteCond %{HTTPS} =off
— Michael Berkowski,

1
Jeśli to zrobię, przekieruje do https: / / ww ww w w.
— bigben

Drogi @bigben, tutaj przyjąłeś złą odpowiedź! możesz dowiedzieć się, dlaczego jest to źle w mojej odpowiedzi .
— Amir Fo

Odpowiedzi:


632

Aby najpierw wymusić HTTPS, musisz sprawdzić poprawną zmienną środowiskową %{HTTPS} off, ale twoja reguła powyżej poprzedza: www.Ponieważ masz drugą regułę do wymuszenia www., nie używaj jej w pierwszej regule.

RewriteEngine On
RewriteCond %{HTTPS} off
# First rewrite to HTTPS:
# Don't put www. here. If it is already there it will be included, if not
# the subsequent rule will catch it.
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Now, rewrite any request to the wrong domain to use www.
# [NC] is a case-insensitive match
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

O pośrednictwie

W przypadku niektórych form proxy, w których klient łączy się za pośrednictwem HTTPS z serwerem proxy, modułem równoważenia obciążenia, aplikacją pasażera itp., %{HTTPS}Zmienna może nigdy nie być onprzyczyną pętli przepisywania. Wynika to z faktu, że aplikacja faktycznie odbiera zwykły ruch HTTP, mimo że klient i serwer proxy / moduł równoważenia obciążenia używają protokołu HTTPS. W takich przypadkach sprawdź X-Forwarded-Protonagłówek zamiast %{HTTPS}zmiennej. Ta odpowiedź pokazuje odpowiedni proces


14
W niektórych przypadkach twój certyfikat może być odpowiedni tylko dla jednej domeny (może współpracować z www, ale nie bez, na przykład). W takich przypadkach najpierw przekieruj do właściwej domeny, a następnie do https, w przeciwnym razie w przeglądarce pojawi się komunikat o błędzie certyfikatu.
— Nick Benson

19
Kiedy użyłem RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]adresu URL takiego jak exaple.com/?bla=%20 stał się exaple.com/?bla=%2520 , tzn. Znak procentu został zakodowany. Rozważ użycie flagi, NEaby zapobiec podwójnemu kodowaniu:RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [NE,L,R=301]
— Pokonaj

5
daje mi to pętlę przekierowania na jednym serwerze, działa na drugim. Naprawdę nie wiem dlaczego
— 15.01.2016

4
@ user151496 Czy serwer, który uległ awarii, używa jakiegokolwiek proxy proxy, na przykład przechodząc przez pamięć podręczną Varnish lub do Passenger? Jeśli tak, może być konieczne sprawdzenie X-Forwarded-Protonagłówka w celu weryfikacji HTTPS zamiast %{HTTPS}zmiennej. Nie powiedziałeś, która część powoduje pętlę, wwwczy część HTTPS, ale to pierwsza rzecz, która przychodzi mi na myśl.
— Michael Berkowski

5
Ściśle mówiąc, dwie powyższe zasady są w niewłaściwej kolejności. Jeśli pojawi się żądanie http://example.com(np. HTTP i nie www), otrzymasz podwójne przekierowanie. Najpierw do https://example.com(pierwsza reguła), a następnie do https://www.example.com(druga reguła). Możesz to naprawić, po prostu odwracając te dwie reguły, ponieważ obie reguły przekierowują na HTTPS niezależnie.
— MrWhite

148

Odpowiedź Michalsa działała dla mnie, choć z jedną małą modyfikacją:

Problem:

gdy masz pojedynczy certyfikat bezpieczeństwa witryny , przeglądarka, która próbuje uzyskać dostęp do Twojej strony bez https: // www. (lub którąkolwiek domenę, którą obejmuje Twój certyfikat) wyświetli brzydki czerwony ekran ostrzegawczy, zanim jeszcze otrzyma przekierowanie na bezpieczną i poprawną stronę https.

Rozwiązanie

Najpierw użyj przekierowania na stronę www (lub dowolną domenę objętą certyfikatem), a dopiero potem przekieruj https. Zapewni to, że Twoi użytkownicy nie będą mieli do czynienia z żadnym błędem, ponieważ przeglądarka widzi certyfikat, który nie obejmuje bieżącego adresu URL.

#First rewrite any request to the wrong domain to use the correct one (here www.)
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

#Now, rewrite to HTTPS:
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

5
+1, ponieważ jest to lepsza opcja dla tego scenariusza, ale należy pamiętać, że nie zapobiegnie to pojawieniu się tego samego problemu, jeśli klient uzyska dostęp https://example.com, ale moim zdaniem jest to najmniej prawdopodobny format, który może wpisać użytkownik. (Przyjęta odpowiedź będzie miała ten sam problem)
— Joshua Goossen

@Larzan: To źle. Wyjątek certyfikacyjny występuje tylko dlatego, że wykonujesz 2 prawdziwe przekierowania. Zamień „[L, R = 301]” na „[R = 301]”. Reguły nie są przerywane. L = OSTATNI
— pokonaj

Jeśli musisz poradzić sobie https://bez wwwposiadania certyfikatu tylko www, po prostu dodaj tę regułę do rozwiązania: RewriteCond %{HTTP_HOST} !^www\. RewriteCond %{HTTPS} on RewriteRule ^(.*)$ http://www.%{HTTP_HOST}%{REQUEST_URI}[L,R=301] po prostu wraca do httppróby połączenia, https://example.comaby uniknąć błędu certyfikatu.
— Eric Burel

1
Te dwie zasady i tak powinny zostać odwrócone (tak jak to zrobiłeś), aby zapobiec podwójnemu przekierowaniu podczas żądania http://example.com(tj. HTTP i brak www)
— MrWhite

@EricBurel W tym przypadku nie można uniknąć błędu certyfikatu - uzgadnianie protokołu SSL następuje przed wykonaniem kodu (co jest sednem protokołu SSL). Jeśli Twoje przekierowanie było w stanie wykonać się przed błędem certyfikatu przeglądarki, oznaczałoby to, że żądanie zostało już wykonane przez niepewne połączenie - co byłoby fundamentalną wadą w modelu SSL.
— MrWhite

99

Jeśli korzystasz z CloudFlare lub podobnego CDN, otrzymasz błąd nieskończonej pętli dzięki rozwiązaniom% {HTTPS} podanym tutaj. Jeśli jesteś użytkownikiem CloudFlare, musisz użyć tego:

RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

2
Uwaga: obecne porady na stronie pomocy technicznej Cloudflare są nieco inne: support.cloudflare.com/hc/en-us/articles/…
— ColinMcDermott

1
Zgadzam się z @ h0mayun, rada Cloudflare daje wyniki w pętli przekierowań, podczas gdy ten kod działa idealnie - dziękuję!
— hobailey

2
Korzystam z angularjs na ec2. Rozwiązania wykorzystujące RewriteCond% {HTTPS}! = On dają mi nieskończone przekierowanie (nie do końca pewne, dlaczego). To rozwiązanie, z X-Forwarded-Proto, wydaje się załatwić sprawę. Dziękuję Ci!
— Mark Watkins,

3
I zmodyfikowane =httpdo !=httpsnaszych środowisk. X-Forwarded-Protonagłówek nie został zadeklarowany, jeśli http, podobnie !=httpszrobiła sztuczka.
— Johnathan Elmore

Dziękuję za ten wgląd! Spędziłem godziny próbując dowiedzieć się, dlaczego {HTTPS}nie działa. Próbowałem, {ENV:HTTPS}a nawet {SERVER_PORT} 443, ale ostatecznie było tak, ponieważ musiałem sprawdzić niestandardowe nagłówki żądań HTTP Cloudflare.
— camslice

56

ZŁE ROZWIĄZANIE I DLACZEGO!

Nigdy nie używaj poniższego rozwiązania, ponieważ kiedy używasz ich kodu, jest to coś takiego:

RewriteCond %{HTTPS} off
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

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

Przeglądarka przechodzi do:

http://example.com

Następnie przekierowuje do:

https://example.com

Następnie przekierowuje do:

https://www.example.com

To za dużo żądań do serwera.

Większość odpowiedzi, nawet zaakceptowanych, ma ten problem.


NAJLEPSZE ROZWIĄZANIE I ODPOWIEDŹ

Ten kod ma [OR]warunek, aby zapobiec podwójnym zmianom w adresie URL!

RewriteEngine on
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule (.*) https://www.example.com%{REQUEST_URI} [R=301,L]

3
„ZŁE ROZWIĄZANIE I DLACZEGO!” - Te zasady są po prostu w niewłaściwej kolejności. Odwróć te dwie zasady i będzie poprawne - dostaniesz tylko jedno przekierowanie, a nie dwie.
— MrWhite

4
Tak, podany kod skutkuje 2 przekierowaniami - nie kwestionuję tego - mówię tylko, że wystarczy odwrócić te reguły, aby rozwiązać ten problem, żadna inna zmiana nie jest wymagana. („Przyjęta” odpowiedź jest rzeczywiście niepoprawna - co wydaje się być tym, o czym mówisz - dyrektywy są w niewłaściwej kolejności.)
— MrWhite

1
Tak, @AmirForsati ma rację. przekierowuje dwa razy i to powinna być zaakceptowana odpowiedź.
— Zakir hussain,

4
Możesz użyć tego, jeśli chcesz zachować zmienną nazwy domeny:RewriteEngine On RewriteCond %{HTTPS} off RewriteCond %{HTTP_HOST} !^www\. [NC] RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301] RewriteCond %{HTTPS} off RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
— I.devries,

Przekierowuje mnie to wp-content/cache/page_enhanced/i tak dalej. Jak mogę to naprawić? Edycja: Wygląda na to, że muszę to umieścić na górze .htaccess. Dzięki za skrypt :)
— Giacomo

35

Jest to najlepszy sposób, jaki znalazłem dla użytkowników proxy, a nie użytkowników proxy

RewriteEngine On

### START WWW & HTTPS

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

# ensure https
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

### END WWW & HTTPS

2
Prawidłowo Jest to najlepszy sposób, jaki znalazłem dla użytkowników proxy, a nie użytkowników proxy +1
— Deep 3015

1
To jest najlepsze, ponieważ rozwiązuje wiele przekierowań 301
— Niraj Chauhan

1
najlepsze rozwiązanie w historii.
— SM Jobayer Alam

1
Świetna odpowiedź. To jedyny, który dla mnie działał. Działa, jeśli jesteś za Cloudflare (chociaż nie mam skonfigurowanych reguł stron w Cloudflare).
— jasonco

Jedyne rozwiązanie, które działa na wszystkich moich przypadkach. Ale co, jeśli chcę to zrobić, usuń wszystkie „www”.
— FedeKrum

27

Istnieje wiele rozwiązań. Oto link do wiki Apache, która bezpośrednio zajmuje się tym problemem.

http://wiki.apache.org/httpd/RewriteHTTPToHTTPS

RewriteEngine On
# This will enable the Rewrite capabilities

RewriteCond %{HTTPS} !=on
# This checks to make sure the connection is not already HTTPS

RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
# This rule will redirect users from their original location, to the same location but using HTTPS.
# i.e.  http://www.example.com/foo/ to https://www.example.com/foo/
# The leading slash is made optional so that this will work either in httpd.conf
# or .htaccess context

Przekonałem RewriteCond %{HTTPS} offsię, RewriteCond %{HTTPS} !=onże zmiana warunku przepisywania z na to przekierowanie zawsze się zdarza, wydaje mi się to lepszą odpowiedzią.
— Samuel Hawksby-Robinson

To rozwiązanie należy zaakceptować jako prawidłową odpowiedź! Pracowałem też dla mnie!
— AndrewShmig,

11

Aby przekierować http: // lub https: // na https: // www , możesz użyć następującej reguły dla wszystkich wersji apache:

RewriteEngine on

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ https://www.example.com%{REQUEST_URI} [NE,L,R]

Apache 2.4

RewriteEngine on

RewriteCond %{REQUEST_SCHEME} http [OR]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ https://www.example.com%{REQUEST_URI} [NE,L,R]

Zauważ, że zmienna% {REQUEST_SCHEME} jest dostępna do użycia od Apache 2.4 .


1
Problem !: Jeśli HTTP_HOST już zawiera www. ale schemat nie jest HTTPS, to kończy się na www.www. u twojego gospodarza.
— Jpsy

@Jpsy masz rację. Zaktualizowałem miejsce docelowe przekierowania. Dzięki za wkład.
— starkeen

1
To jest prawie to, czego szukałem, ale chcę zachować domenę ogólną, jak w innych przykładach. Czy to możliwe?
— cronoklee

8

Jeśli korzystasz z CloudFlare, upewnij się, że używasz czegoś takiego.

# BEGIN SSL Redirect
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
# END SSL Redirect

To uratuje Cię od pętli przekierowań i bezpiecznie przekieruje twoją stronę na SSL.

PS Dobrym pomysłem jest sprawdzenie mod_rewrite.c!


nie przekierowuje https: // theurlwithoutwww.com na https: // www.
— tearentthedroids

Jest to faktycznie działające rozwiązanie tylko wtedy, gdy masz wcześniej kilka dyrektyw „dodaj www”. Inne rozwiązania dają mi „do wielu przekierowań”.
— Daniel.P.


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

Uwagi: Upewnij się, że wykonałeś następujące kroki

  1. sudo a2enmod przepisz
  2. usługa sudo apache2 restart
  3. Dodaj następujące w pliku vhost, znajdującym się w /etc/apache2/sites-available/000-default.conf
<Directory /var/www/html>
  Options Indexes FollowSymLinks MultiViews
  AllowOverride All
  Order allow,deny
  allow from all
  Require all granted
</Directory>

Teraz Twój .htaccess będzie działał, a Twoja strona przekieruje na http: // na https: // www



0

Ustaw w pliku .htaccess

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


-2

Próbuję pierwszej odpowiedzi i to nie działa ... Ta praca:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

RewriteCond %{ENV:HTTPS} !=on
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R,L]

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.