Я знаю о канонический вопрос и прочитал это, но, кажется, я не могу найти там кое-что.
Вот мои условия и правила, чтобы отказаться www
и сила https
:
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L,NE]
RewriteCond %{HTTPS} off
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]
Я понимаю, что пытаюсь сопоставить. Однако мне немного непонятны правила замены. Я не понимаю:
www.
) в конечном итоге в %1
?Причина второго вопроса в том, что руководство прямо заявляет (выделено мной):
REQUEST_URI
Компонент пути запрошенного URI, например "/index.html". Это, в частности, исключает строку запроса который доступен как собственная переменная с именем QUERY_STRING.
Я предполагаю, что эти директивы работают нормально, и вам нужно только объяснить, почему?
- Как мое имя хоста (без
www.
) в конечном итоге в%1
?
%1
это обратная ссылка к первой захваченной группе в последнем сопоставленном CondPattern. Итак, при следующем условии:
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
Регулярное выражение (т.е. CondPattern) ^www\.(.*)$
сопоставляется с HTTP_HOST
серверная переменная. Матч считается успешным, когда HTTP_HOST
удовлетворяет регулярному выражению ^www\.(.*)$
, который www.
с последующим что-нибудь. Который что-нибудь является частью захваченной группы (заключенный в скобки подшаблон). т.е. (.*)
не просто .*
. Все, что соответствует (.*)
группа сохраняется в %1
обратная ссылка и может быть использована позже в RewriteRule
замена. Например, учитывая запрос на www.example.com/something
, это становится:
RewriteCond www.example.com ^www\.(.*)$ [NC]
%1
поэтому будет содержать example.com
.
Почему не теряется строка запроса при применении второго правила?
Потому что, если вы явно не включите строку запроса в RewriteRule
замена тогда строка запроса из запроса автоматически добавляется в конец полученного замена.
Однако, если вы включили строку запроса в конец замена, даже просто пустую строку запроса ( ?
за которым ничего не следует), то строка запроса из запроса не добавляется. Например:
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI}? [R=301,L,NE]
Это приведет к тому, что строка запроса будет удалена из запроса (обратите внимание на конечный ?
). В качестве альтернативы в Apache 2.4+ вы можете использовать QSD
(Отмена строки запроса), чтобы запретить добавление строки запроса.
В стороне: Я также убрал круглые скобки из RewriteRule
шаблон. Здесь вам не нужна захваченная группа, так как вы используете REQUEST_URI
вместо этого серверная переменная. (Это будет доступно в $1
обратная ссылка - обратите внимание на $
префикс. Хранение обратных ссылок, когда они вам не нужны, - это пустая трата ресурсов и затрудняет читаемость.)
RewriteCond %{HTTP:X-Forwarded-Proto} !https
Я предполагаю, что ваш сервер находится за прокси-сервером, который устанавливает X-Forwarded-Proto
заголовок?