Я знаю канонический вопрос и прочитал его, но, похоже,
Вот мои условия и правила для удаления 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
?