перенаправлення htaccess на https: // www


309

У мене є такий код 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>

Я хочу, щоб мій сайт був переспрямований на https://www.HTTPS та примусовий www.піддомен, але коли я отримую доступ http://www.(без HTTPS), він не переспрямовує мене https://wwwз HTTPS.


Має бутиRewriteCond %{HTTPS} =off
Майкл Берковський

1
Якщо я це зробив, він перенаправляє на https: / / ww ww w w.
bigben

Шановний @bigben, ти прийняв тут неправильну відповідь! ви можете дізнатися, чому це неправильно в моїй відповіді .
Амір Фо

Відповіді:


632

Щоб спершу застосувати HTTPS, ви повинні перевірити правильну змінну середовища %{HTTPS} off, але ваше правило вище, ніж тоді, передує, www.оскільки у вас є друге правило для виконання www., не використовуйте його в першому правилі.

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]

Про наближення

Якщо за деякими формами наближення, коли клієнт підключається через HTTPS до проксі, балансира завантаження, пасажирської програми тощо, ця %{HTTPS}змінна ніколи не може бути onі викликати цикл перезапису. Це тому, що ваша програма насправді отримує звичайний трафік HTTP, навіть якщо клієнт та проксі / балансир завантаження використовують HTTPS. У цих випадках перевірте X-Forwarded-Protoзаголовок замість %{HTTPS}змінної. Ця відповідь показує відповідний процес


14
У деяких випадках ваш сервер може бути корисним лише для одного домену (він може працювати з www, але, не без цього, наприклад). У таких випадках спочатку перенаправляйте на правильний домен, а потім перенаправляйте на https, інакше у вашому браузері з’явиться повідомлення про помилку cert.
Нік Бенсон

19
Коли я використовував RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]таку URL-адресу, як exaple.com/?bla=%20, став exaple.com/?bla=%2520 , тобто знак відсотка був закодований. Подумайте про використання прапора NEдля запобігання подвійного кодування:RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [NE,L,R=301]
Бийте

5
це дає мені цикл переадресації на одному сервері, працює на іншому. я дійсно не знаю, чому
користувач151496

4
@ user151496 Чи відмовний сервер використовує будь-який тип HTTP-проксі, як, наприклад, проходження через кеш лаку чи в пасажирський? Якщо так, можливо, вам доведеться перевірити X-Forwarded-Protoзаголовок, щоб перевірити HTTPS замість %{HTTPS}змінної. Ви не сказали, яка частина викликає цикл, wwwабо частина HTTPS, але це перше, що мені спадає на думку.
Michael Berkowski

5
Власне кажучи, два вищезазначені правила - у неправильному порядку. Якщо надходить запит на http://example.com(наприклад, HTTP та non-www), ви отримаєте подвійне переспрямування. Спочатку до https://example.com(перше правило), а потім до https://www.example.com(друге правило). Це можна виправити, просто повернувши ці два правила, оскільки обидва правила перенаправляють на HTTPS незалежно.
MrWhite

148

Відповідь Міхалса працював на мене, хоча і з однією невеликою модифікацією:

Проблема:

коли у вас є один сертифікат безпеки сайту , браузер, який намагається отримати доступ до вашої сторінки без https: // www. (або який би домен не охоплював ваш сертифікат) відображатиметься некрасивий червоний екран попередження, перш ніж він навіть отримає переадресацію на безпечну та правильну сторінку https.

Рішення

Спочатку скористайтеся переспрямуванням на www (або залежно від домену, який охоплює ваш сертифікат), і лише після цього виконайте перенаправлення https. Це забезпечить, щоб ваші користувачі не стикалися з жодною помилкою, оскільки ваш браузер бачить сертифікат, який не покриває поточну 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, оскільки це кращий варіант для цього сценарію, але зауважте, що це не завадить https://example.comвиникнути тій же проблемі, якщо клієнт має доступ , але, на мою думку, це найменш вірогідний формат, який слід вводити користувачем. (Прийнята відповідь також матиме ту саму проблему)
Джошуа Гуссен

@Larzan: Це неправильно. Виняток із сертифікації має місце лише тому, що ви робите 2 реальні переадресації. Замініть "[L, R = 301]" на "[R = 301]". Ці правила не скасовуються. L = ОСТАННЯ
дефіле

Якщо вам потрібно обробитись, https://не wwwмаючи сертифіката лише на www, просто додайте це правило до рішення: RewriteCond %{HTTP_HOST} !^www\. RewriteCond %{HTTPS} on RewriteRule ^(.*)$ http://www.%{HTTP_HOST}%{REQUEST_URI}[L,R=301] воно просто повертається до httpспроби підключення, https://example.comщоб уникнути помилки сертифіката.
Ерік Бурель

1
Обидва правила слід змінити в будь-якому випадку (як ви це зробили), щоб уникнути подвійного переадресації при запиті http://example.com(наприклад, HTTP і не www)
MrWhite

@EricBurel У цьому випадку ви не можете уникнути помилки cert - рукостискання SSL відбувається перед виконанням вашого коду (в першу чергу вся суть SSL). Якщо ваше перенаправлення вдалося виконати перед помилкою cert-браузера, то це означатиме, що запит вже був зроблений через незахищене з'єднання - що було б принциповим збоєм в моделі SSL.
MrWhite

99

Якщо ви використовуєте CloudFlare або подібний CDN, ви отримаєте нескінченну помилку циклу із рішеннями% {HTTPS}, наданими тут. Якщо ви користуєтесь CloudFlare, вам потрібно буде скористатися цим:

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

2
Зверніть увагу, що поточна порада на веб-сайті підтримки Cloudflare дещо відрізняється: support.cloudflare.com/hc/en-us/articles/…
ColinMcDermott

1
Погодьтеся з @ h0mayun, порада Cloudflare дає результат перенаправлення циклу, тоді як цей код тут чудово працює - дякую!
hobailey

2
Я запускаю angularjs на ec2. Рішення з використанням RewriteCond% {HTTPS}! = On дають мені нескінченне перенаправлення (не зовсім впевнений, чому). Це рішення, з X-Forwarded-Proto, здається, робить свою справу. Дякую!
Марк Уоткінс

3
Я змінив =httpв !=httpsнаших умовах. X-Forwarded-ProtoЗаголовок не оголошено, якщо http, так !=httpsсамо і трюк.
Джоннатан Елмор

Дякую за це розуміння! Я витрачав години, намагаючись з’ясувати, чому {HTTPS}не працює. Я намагався {ENV:HTTPS}і навіть {SERVER_PORT} 443, але врешті-решт, це було тому, що мені потрібно було перевірити, чи власні HTTP-заголовки запиту Cloudflare.
camslice

56

БАД РІШЕННЯ І ЧОМУ!

Ніколи не використовуйте рішення нижче, оскільки коли ви використовуєте їх код, це щось на зразок:

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]

Переглядач переходить до:

http://example.com

Потім переспрямовується на:

https://example.com

Потім переспрямовується на:

https://www.example.com

Це занадто багато запитів до сервера.

У більшості відповідей, навіть прийнятих, є ця проблема.


НАЙКРАЩЕ РІШЕННЯ ТА ВІДПОВІДЬ

Цей код має [OR]умову запобігати подвійним змінам за URL-адресою!

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

3
"БАД РІШЕННЯ І ЧОМУ!" - Ці правила просто в неправильному порядку. Поверніть ці два правила, і це буде правильно - ви отримаєте лише одне переадресацію, а не два.
MrWhite

4
Так, код, як це дано в двох переадресаціях - я не заперечую це - все, що я говорю, - вам просто потрібно змінити ці правила, щоб вирішити цю проблему, ніяких інших змін не потрібно. (Відповідь "прийнята" дійсно невірна - це, мабуть, те, на що ви посилаєтесь, - директиви в неправильному порядку.)
MrWhite

1
yup @AmirForsati має рацію. це переадресація двічі, і це має бути прийнятою відповіддю.
Закір Хусей

4
Ви можете використовувати це, якщо хочете зберегти змінну 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]
доменного імені

Це перенаправлення мене на, wp-content/cache/page_enhanced/а потім так далі. Як я можу це виправити? Редагувати: Схоже, мені потрібно поставити його вгорі .htaccess. Дякую за сценарій :)
Джакомо

35

Це найкращий спосіб, який я знайшов для користувачів проксі, а не для проксі

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
Правильно Це найкращий спосіб, який я знайшов для користувачів проксі, а не проксі +1
глибоке 3015,

1
Це найкращий варіант, оскільки він вирішує кілька переадресацій 301
Niraj Chauhan

1
найкраще рішення будь-коли.
SM Jobayer Alam

1
Чудова відповідь. Це єдиний, хто працював на мене. Працює, якщо ви стоїте за Cloudflare (хоча у мене немає правил, встановлених на сторінці у Cloudflare).
Jasonco

Єдине рішення, яке працює у всіх моїх справах. Але що робити, якщо я хочу зробити de oposite та видалити всі "www".
FedeKrum

27

Є багато рішень там. Ось посилання на вікі apache, яка безпосередньо займається цим питанням.

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

Я знайшов, змінивши умову переписування з RewriteCond %{HTTPS} offтого, RewriteCond %{HTTPS} !=onщо перенаправлення завжди відбуватиметься, це здається мені кращою відповіддю.
Семюель Хоксбі-Робінсон

Це рішення слід сприймати як правильну відповідь! Працював і для мене!
АндрійШміг

11

Для перенаправлення http: // або https: // на https: // www ви можете використовувати таке правило для всіх версій 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]

Зауважте, що змінна% {REQUEST_SCHEME} доступна для використання з apache 2.4 .


1
Проблема !: Якщо HTTP_HOST вже містить www. але схема не HTTPS, тоді ви закінчуєте www.www. у вашого господаря.
Jpsy

@Jpsy ви праві. Я оновив напрямок перенаправлення. Дякуємо за ваш внесок
starkeen

1
Це майже те, що я шукав, але хочу зберегти загальний домен, як в інших прикладах. Це можливо?
cronoklee

8

Якщо ви перебуваєте на CloudFlare, переконайтеся, що ви використовуєте щось подібне.

# 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

Це позбавить вас від циклу переадресації та безпечно перенаправить ваш сайт на SSL.

PS Добре, якщо перевірити mod_rewrite.c!


вона не перенаправляє https: // theurlwithoutwww.com на https: // www.
ціаренттедроїди

Це насправді лише робоче рішення, якщо ви маєте заздалегідь деякі директиви "додати www". Інші рішення дають мені "багато переадресацій".
Даніель.P.


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

Примітки. Переконайтеся, що ви виконали наступні дії

  1. переписати sudo a2enmod
  2. перезапуск служби sudo служби apache2
  3. Додайте наступне у свій файл vhost, який знаходиться за адресою /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>

Тепер ваш .htaccess буде працювати, і ваш веб-сайт буде перенаправлений на http: // до https: // www



0

Встановіть у своєму файлі .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

Я спробую спочатку відповісти, і це не працює ... Ця робота:

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