Я пытаюсь уменьшить количество цепочек переадресации 301 на моем сервере, поэтому я хотел бы объединить поддомен с переадресацией без www (кроме случаев, когда поддомен dev
) с перенаправлением HTTP на HTTPS (используя %{HTTP:X-Forwarded-Proto}
), поскольку экземпляр находится за балансировщиком нагрузки.
Вот что у меня в .htaccess
:
# move http to https
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=301]
# Remove leading www
RewriteCond %{HTTP_HOST} ^www.example.net [NC]
RewriteRule ^(.*)$ https://example.net/$1 [R=301,L]
В моей нынешней реализации есть три проблемы:
Просьба к http://www.example.net
будет два редиректа.
Как и большинство примеров перенаправления с www на не-www на этом сайте, он не перенаправляет ww.
или wwww.
поэтому в моей аналитике есть много неправильно введенных поддоменов, которые не были перенаправлены.
Я бы хотел исключить dev.
поддомен из перенаправления, поэтому http://dev.example.net
и это https
брат, как я использую dev.
для разработки и постановки релизов.
Как мне это объединить?
# Remove leading www, always using https regardless of the current URL scheme
RewriteCond %{HTTP_HOST} ^w{2,4}.example.net(?::|$) [NC,NV]
RewriteRule .* https://example.net%{REQUEST_URI} [L,R=301]
# move http to https, except for dev.example.net
RewriteCond %{HTTP:X-Forwarded-Proto} =http [NC,NV]
RewriteCond %{HTTP_HOST} !^dev.example.net(?::|$) [NC,NV]
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
NC
(nocase
) флаг в X-Forwarded-Proto
условие, так как его значение казалось неважным, т.е. HTTP = Http = hTTp = http
. Вы можете удалить это.NV
(novary
) флаг в X-Forwarded-Proto
условие, чтобы скрыть это от Vary
заголовок ответа. Опять же, вы можете удалить это, особенно если это не так (обратный прокси-сервер все равно автоматически фильтрует его перед отправкой клиенту) или необходимо для правильного поведения кеширования (в противном случае кеш не различает http
и https
содержание).NV
(novary
) флаг в Host
условие заголовка, чтобы скрыть его от Vary
заголовок ответа. Вы также можете удалить это, если у вас сломался кеш-сервер.RewriteRule
порядок флагов согласован (L,R=301
и R=301,L
по сути одинаковы).www.example.net.but.not.actually.yours.com
от признания, но все же позволяет, например, www.example.net:443
.%{REQUEST_URI}
в качестве замены.ww
и wwww
.1) Обращение к
http://www.example.net
будет два редиректа.
Это можно решить, просто поменяв местами два правила. затем www.example.net
перенаправляется на HTTPS при первом перенаправлении, поэтому перенаправление HTTP на HTTPS запускать не нужно.
(Это, однако, предполагает, что вы не собираетесь реализовывать HSTS - в этом случае вам нужно будет сохранить их как два перенаправления с момента перенаправления на HTTPS на одном и том же имени хоста первый это требование.)
2) Как и большинство примеров перенаправления с www на не-www на этом сайте, он не перенаправляет
ww.
илиwwww.
поэтому в моей аналитике есть много неправильно введенных поддоменов, которые не были перенаправлены.
Обычно запросы ww.
или wwww.
субдомены просто не разрешаются, так что обычно это не проблема. Чтобы это работало, вам необходимо настроить подстановочный знак поддомен в DNS и настроил сервер для приема таких запросов.
Но это можно объяснить, изменив регулярное выражение (фрагмент) из ^www\.
к ^w{2,4}\.
.
3) Я хочу исключить
dev.
поддомен из перенаправления, поэтомуhttp://dev.example.net
и этоhttps
брат, как я используюdev.
для разработки и постановки релизов.
Это применимо только к правилу HTTP to HTTPS, поэтому здесь можно применить дополнительное условие для исключения имен хостов, начинающихся с dev.
.
Объединив указанные выше моменты, попробуйте следующее:
# Remove leading ww, www or wwww (and redirect to HTTPS)
RewriteCond %{HTTP_HOST} ^w{2,4}\.example\.net [NC]
RewriteRule (.*) https://example.net/$1 [R=301,L]
# Move http to https (except dev subdomain)
RewriteCond %{HTTP:Host} !^dev\. [NC]
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^ https://%{HTTP:Host}%{REQUEST_URI} [R=301,L]
Я продолжал использовать HTTP:Host
то же самое (чтобы получить доступ к Host
Заголовок HTTP-запроса), если это требование балансировщика нагрузки? В противном случае чаще используют HTTP_HOST
здесь переменная сервера.
В !
префикс на CondPattern (т.е. !^dev\.
) отменяет регулярное выражение, поэтому условие выполняется, когда Host
делает не начать с dev.
. (Я предполагаю www.dev.
не вещь?)
(.*)
такой же как ^(.*)$
поскольку регулярное выражение по умолчанию является жадным.
Перед тестированием вам необходимо очистить кеш браузера. Желательно сначала протестировать с 302 (временными) перенаправлениями, чтобы избежать проблем с кешированием.