Mode_rewrite в подробностях. Часть 2

В прошлый раз мы рассмотрели полный цикл работы mode_rewrite, однако остались неосвещенными некоторые важные моменты. О них мы и поговорим

Mode_rewrite флаги

Как вам наверное известно, каждая директива RewriteRule может иметь на конце необязательный набор флагов, регулирующих ее действие и изменяющих действие редиректа в .htaccess. Мы рассмотрим самые интересные и важные флаги:

  • [L] — остановка процесса преобразований.
  • [R] — вызов редиректа.
  • [QSA] — добавление (по умолчанию замена) строки запроса.

[L]:остановка обработки mode_rewrite

Как вы уже поняли, добавление флага [L] позволяет остановить процесс обработки запроса, т.е. все последующие правила не будут применены. Использование данного флага иногда очень удобно, но стоит помнить о двух возможных ошибках.

Флаг [L] прерывает только текущую итерацию обработки. В прошлый раз я рассказал, как работает mod_rewrite и показал, что запросы обрабатываются до тех пор, пока исходная строка не совпадет с результатом преобразований. Использование флага [L] не отменяет этого правила.

Следующая проблема является следствием предыдущей. В случае частого использования флага [L] может возникнуть трудно отлавливаемое зацикливание процесса обработки, вывызвающее внутреннюю ошибку сервера. Приведу пример:

RewriteBase /

RewriteRule ^test1.html$ test2.html [L]

RewriteRule ^test2.html$ test1.html [L]

Запрос любого из двух документов вызовет бесконечный цикл преобразований. В случае отсутствия флагов такого не произойдет, т.к. исходный и конечный запрос совпадают.

[R]:редирект в mode_rewrite

Данный флаг прямо указывает, что должен быть произведен внешний редирект. Это означает, что ответ сервера будет содержать код редиректа 301 или 302, а адрес в строке браузера изменится (в случае внутреннего редиректа пользователь не может узнать о нем).

Следует помнить, что apache не производит редирект сразу, встретив флаг [R], а лишь запоминает о необходимости выполнить внешний редирект. Как правило мы хотим противоположного поведения, поэтому практически всегда следует использовать связку двух флагов: [R=301,L] — сделать 301 редирект и прервать дальнейшие преобразования. Кроме того, как я уже писал в предыдущей части статьи, при указании полной внешней ссылки, редирект автоматически становится внешним.

[QSA]: изменение параметров запроса в mode_rewrite

Параметры запроса не входят в саму строку, с которой оперирует RewriteRule, однако если во второй половине директивы к строке добавляются параметры запроса — они передаются в переменную %{QUERY_STRING}, которую можно использовать в RewriteCond. Важно, что эта часть строки не попадает в основную, с которой будут работать следующие директивы. Флаг [QSA] регулирует порядок добавления новых параметров запроса в %{QUERY_STRING}. По умолчанию происходит перезапись параметров, при наличии флага [QSA], новые параметры добавляются в начало %{QUERY_STRING}. Важно, что %{QUERY_STRING} изменятся сразу же в данном правиле, поэтому в последующих правилах может возникнуть проблема при необходимости узнать исходные параметры запроса пользователя. Решение приведено в одном из практических примеров работы с mode_rewrite.

RewriteCond: условия для RewriteRule

После того как мы разобрались с особенностями отработки RewriteRule и основных флагов, осталось поговорить о RewriteCond, которые являются аналогом оператора if, только с длинным названием)).

В общем случае применение RewriteCond выглядит примерно так:

RewriteEngine on

RewriteCond условие1

RewriteCond условие2

RewriteRule правило 1

RewriteRule правило 2

В данном случае правило 1 будет применено, если выполняются условия 1 и 2, а правило 2 исполнится всегда, т.к. RewriteCond действует только на следующее непосредственно за ним RewriteRule. Для группировки RewriteCond можно использовать логический флаг [OR] (по умолчанию подразумевается AND).

Основные возможности RewriteCond заключаются в применении следующих «фишек»:

  • $N (N — число от 1 до 9) — доступ к частям директивы RewriteRule;
  • %N (N — число от 1 до 9) — доступ к частям директивы RewriteCond;
  • %{NAME_OF_VARIABLE} — использование нижеприведенных переменных запроса
 HTTP_USER_AGENT Содержит информацию о типе и версии браузера и операционной системы посетителя.
 HTTP_REFERER Приводится адрес страницы, с которой посетитель пришёл на данную страницу.
 HTTP_COOKIE Список COOKIE, передаваемых браузером
 HTTP_FORWARDED Страница непосредственно, с которой перешел пользователь
 HTTP_HOST Адрес сервера
 HTTP_ACCEPT Описываются предпочтения клиента относительно типа документа.
 REMOTE_ADDR IP-адрес посетителя.
 REMOTE_HOST адрес посетителя в нормальной форме
 REMOTE_IDENT Имя удаленного пользователя. Имеет формат имя.хост
 REMOTE_USER Тоже, что и REMOTE_IDENT, но содержит только имя.
 REQUEST_METHOD Позволяет определить тип запроса (GET или POST). Должен обязательно анализироваться, т.к. определяет дальнейший способ обработки информации
 SCRIPT_FILENAME Полный путь к веб-странице на сервере.
 PATH_INFO Содержит в себе все, что передавалось в скрипт.
 QUERY_STRING Содержит строчку, переданную в качестве запроса при вызове CGI скрипта.
 AUTH_TYPE Используется для идентификации пользователя
 DOCUMENT_ROOT Cодержит путь к корневой директории сервера.
 SERVER_ADMIN Почтовый адрес владельца сервера, указанный при установке.
 SERVER_NAME Адрес сервера
 SERVER_ADDR IP-адрес вашего сайта.
 SERVER_PORT Порт, на котором работает Apache.
 SERVER_PROTOCOL Версия HTTP протокола.
 SERVER_SOFTWARE Название сервера, например, Apache/1.3.2 (Unix)
 TIME_YEAR
 TIME_MON
 TIME_DAY
 TIME_HOUR
 TIME_MIN
 TIME_SEC
 TIME_WDAY
 TIME
 Переменные предназначены для работы со временем в разных форматах.
 API_VERSION Это версия API модуля Apache (внутренний интерфейс между сервером и модулем) в текущей сборке сервера, что определено в include/ap_mmn.h.
 THE_REQUEST Полная строка HTTP запроса отправленная браузером серверу (т.е., «GET /index.html HTTP/1.1»). Она не включает какие-либо дополнительные заголовки отправляемые браузером.
 REQUEST_URI Ресурс, запрошенный в строке HTTP запроса.
 REQUEST_FILENAME Полный путь в файловой системе сервера к файлу или скрипту соответствующим этому запросу.
 IS_SUBREQ Будет содержать текст «true» если запрос выполняется в текущий момент как подзапрос, «false» в другом случае. Подзапросы могут быть сгенерированы модулями которым нужно иметь дело с дополнительными файлами или URI для того чтобы выполнить собственные задачи.

RewriteCond, как и RewriteRule использует Perl-совместимые регулярные выражения, однако с несколькими дополнениями:

  • Префикс ‘!’ для указания несоответствия шаблону.
  • ‘<Условие’ (лексически меньше)
  • ‘>Условие’ (лексически больше)
  • ‘=Условие’ (лексически равно)
  • ‘-d’ (является ли каталогом)
  • ‘-f’ (является ли обычным файлом)
  • ‘-s’ (является ли обычным файлом с ненулевым размером)
  • ‘-l’ (является ли символической ссылкой)
  • ‘-F’ (проверка существования файла через подзапрос)
  • ‘-U’ (проверка существования URL через подзапрос)

Интересным моментом является порядок проверки условий в mode_rewrite. Он поступает нетривиально и сначала проверяет условие в RewriteRule и если оно выполняется проверяет соответствующие RewriteCond. Поэтому использование RewriteCond для увеличения производительности не имеет смысла.

Я снова устал писать, однако на этом ВСЕ. Осталось лишь привести много практических примеров работы с mod_rewrite, но это будет тема отдельного поста.

oroom

oroom

меня зовут Дмитрий и я автор этого блога, в котором рассказываю о seo, создании сайтов и своем опыте на этом поприще.

3 комментария
Показать все Самые популярные Высокий рейтинг Низкий рейтинг Добавьте свой отзыв
  1. Как все понятно написано. А то в универе вообще непонятно рассказывают. Спасибо.

  2. Да, действительно чётко написано. Я хоть лучше понял механизм работы флага [L], а то раньше иногда возникало зацикливание, потому что я считал его прерыванием цикла, а он прерывает лишь итерацию. И т.к. не было такого понятного мануала, то просто подгонял под рабочий вариант

  3. Здравствуйте уважаемый Дмитрий. Скажите пожалуста, можно ли с Вашим блогом обменяться постовыми. Мой блог в имени. Обмен постовыми почта моя mozdok939@yandex.ru За ранее Вам благодарен!!!

Оставить ответ

SEO эксперты
Logo
Включить регистрацию в настройках - общий