Назад | Перейти на главную страницу

Что я делаю с mod_rewrite?

Я знаю о канонический вопрос и прочитал это, но, кажется, я не могу найти там кое-что.

Вот мои условия и правила, чтобы отказаться 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]

Я понимаю, что пытаюсь сопоставить. Однако мне немного непонятны правила замены. Я не понимаю:

  1. Как мое имя хоста (без www.) в конечном итоге в %1?
  2. Почему не теряется строка запроса при применении второго правила?

Причина второго вопроса в том, что руководство прямо заявляет (выделено мной):

REQUEST_URI

Компонент пути запрошенного URI, например "/index.html". Это, в частности, исключает строку запроса который доступен как собственная переменная с именем QUERY_STRING.

Я предполагаю, что эти директивы работают нормально, и вам нужно только объяснить, почему?

  1. Как мое имя хоста (без 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 заголовок?