
Я пытаюсь сократить количество цепочек перенаправлений 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.
для разработки и подготовки к выпуску.
Как мне это объединить?
решение1
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-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 (временными) перенаправлениями, чтобы избежать проблем с кэшированием.
решение2
# 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
.