НЕ МОЛЧИ!!!    Сделай что-нибудь, чтобы остановить войну России в Украине.
...бойтесь людей равнодушных - именно с их молчаливого согласия происходят все самые ужасные преступления на свете.   ("Репортаж с петлёй на шее")

Инструкции сложного редиректа

Описываются инструкции сложного редиректа с использованием mod_rewrite модуля. Приведены актуальные примеры редиректа. Полученные знания будут достаточны для практического использования файла .htaccess в управлении web сервером.

Содержание

  • Основы редиректа
  • Основные инструкции редиректа
  • Примеры инструкций редиректа

Основы редиректа

Что вы узнаете сегодня? Сначала познакомитесь с основными правилами использования и синтаксисом инструкций, а в конце приведен ряд примеров для закрепления навыков их применения. Поскольку основой редиректа является использование регулярных выражений, ниже приведена небольшая шпаргалка по этому мощному инструменту.

В регулярных выражениях допустимы любые печатные символы и пробел, при этом часть символов, кроме обычного отображения, может использоваться в качестве управляющих. В частности:

  • символ ^ обозначает начало строки;
  • символ $ обозначает конец строки;
  • круглые скобки () используются для выделения группы символов. Такие группы имеют порядковый номер по мере их появления. По этому номеру к ним можно в дальнейшем обратиться;
  • Квадратные скобки [] используются для перечисления допустимых символов, например, [абвг], набор символов можно указывать через дефис, например, предыдущий перечень будет выглядеть [а-г];
  • Квадратные скобки с символом карет в начале [^] используются для перечисления недопустимых символов, например, [^абвг] будет соответствовать любому символу, кроме a,б,в,г;
  • символ | используется в значении ИЛИ;
  • если управляющий символ надо использовать в качестве обычного, перед ним ставится обратный слеш, например, выражение \. — позволит отобразить точку;
  • символ # означает начало комментариев;
  • символ точки . обозначает любой символ, кроме символа новой строки;
  • Символ ? означает, что предшествующее выражение может присутствовать 0 или 1 раз;
  • Символ * означает, что предшествующее выражение может как отсутствовать, так и присутствовать неограниченное число раз подряд, т.е., 0 или N раз;
  • символ + означает, что предшествующий символ должен присутствовать хотя бы один раз, т.е., 1 или N раз;
  • в регулярных выражениях широко используются переменные, которые представляют собой выражение вида %{HTTP_HOST}. В конце статьи в таблице представлен ряд таких переменных, которые используются при редиректе.

Немного примеров.
1. Выражение ниже означает любое количество символов в строке, от 0 до N.
^(.*)$

2. %{REQUEST_URI} — подстрока запроса, которая идет после доменного имени.

3. %{QUERY_STRING} — подстрока GET запроса — то, что стоит в адресной строке запроса после знака ?

4. %{REQUEST_FILENAME} — часто используется для проверки, является ли запрос к файлу или папке. Вид проверки определяется по флагам, -f или -d, файл или папка соответственно.

В отличие от простого редиректа, описанного в статье Инструкции .htaccess, здесь рассказывается о перенаправлении запросов с помощью модуля mod_rewrite. Вы сможете освоить сложный редирект(от английского redirect — перенаправление). Но прежде чем заняться изучением непосредственно инструкций редиректа, надо пояснить, как эти инструкции работают. Для начала уточним, что mod_rewrite обеспечивает перезапись(модификацию) на лету URL адресов, запрошенных у сервера. Не лишним будет знать, что модуль может по разному работать в дополнительном файле конфигурации .htaccess и основном файле конфигурации httpd.conf. Все, что описано ниже касается работы модуля в файле .htaccess.

Надо заметить, что с помощью файлов .htaccess можно осуществлять весьма сложные преобразования. Для отладки таких преобразований в модуле mod_rewrite предусмотрено протоколирование своих действий. Но это уже тема для отдельной статьи.

А пока перечислим основные инструкции, используемые при сложном редиректе. Более полный список инструкций можно отыскать здесь с учетом предпоследней колонки таблицы, которая определяет, где возможно использование директивы.

Основные инструкции редиректа

При проведении редиректа основными являются инструкции RewriteRule и RewriteCond. При редиректе допускается использовать неограниченное число правил RewriteRule и неограниченное число условий RewriteCond для каждого правила. Казалось бы логично предположить, что при редиректе вначале проверяются условия RewriteCond, а затем выполняются правила RewriteRule. В действительности же все наоборот. Модуль mod_rewrite перебирает набор правил одно за другим, каждый набор правил состоит из директив RewriteRule, с или без RewriteCond. Т.е. цикл обработки начинается с обработки инструкций RewriteRule. В начале обработки формируется строка шаблона, и если запрос соответствует шаблону(pattern) правила, происходит дальнейшая его проверка на соответствие всем условиям RewriteCond в том порядке, как они перечислены. Если перед инструкцией RewriteRule нет инструкций RewriteCond, то производится модификация запроса по RewriteRule.

Инструкция RewriteRule

Синтаксис

    RewriteRule pattern substitution [flags],

где
pattern — строка шаблона, которой должен удовлетворять URL запроса;
substitution — строка, которой может быть заменен входящий URL, если он соответствует шаблону текущего правила и удовлетворяет условиям RewriteCond.
В строке может быть указан:
  — путь к нужному ресурсу в файловой системе сервера;
  — относительный путь от корневой директории документов(DocumentRoot);
  — абсолютный URL;
  — тире, которое означает, что соответствующий шаблону путь не требует изменений.
Кроме обычного текста строка шаблона позволяет использовать отдельные свои части и другие переменные. Сделать это можно следующим образом:
— ($N) — ссылки на части шаблона текущей инструкции RewriteRule. Ссылка представляется в виде $N (0 <= N <= 9), которая замещается содержимым соответствующей N-ой группой согласованного шаблона;
— (%N) — ссылки на части согласованного шаблона прошлой инструкции RewriteCond;
— %{VARNAME} — переменные сервера.
— (${mapname:key|default}) — mapping-function вызовы.
Пример использования:

[flags] — флаги для дополнительного управления работой инструкции, представляют собой заключенный в квадратные скобки список символов(или набор символов), разделенных запятыми . Более подробно флаги описаны ниже.

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

Флаги инструкции RewriteRule

Для дополнительного управления работой RewriteRule используются различные флаги, приведем список некоторых из них:

  • ‘cookie|CO=NAME:VAL:domain[:lifetime[:path]]’ — позволяет при совпадении с шаблоном записывать куки.
  • ‘forbidden|F’ — возвращает браузеру клиента отклик 403 FORBIDDEN (запрещено).
  • ‘gone|G’ — флаг заставляет возвращать клиенту код 401 (GONE), означающий, что ресурс больше недоступен.
  • ‘H|handler’ — предписывает результирующий запрос обрабатывать специальным указанным обработчиком.
  • ‘last|L’ — предписывает модулю mod_rewrite прекратить обработку набора правил, т.е. выполнить текущее правило без учета следующих правил.
  • ‘nocase|NC’ — предписывает не учитывать регистр букв.
  • ‘noescape|NE’ — по умолчанию специальные символы, & и ? конвертируются в свой шестнадцатеричный эквивалент, использование флага [NE] предотвращает такое преобразование.
  • ‘qsappend|QSA’ — добавлять строку запроса, флаг предписывает подстроку запроса строки замещения добавлять в существующую строку, а не заменять ее.
  • ‘type|T=MIME-type’ — устанавливает MIME тип ответа сервера. Дает тот же результат, что и инструкция AddType.

Подробнее по флагам и особенностям их применения ищите в Интернете или смотрите первоисточник(en).

К списку инструкций сложного редиректа.

Инструкция RewriteCond

Определяет условие, при выполнении которого происходит преобразование запроса. Для каждой инструкции RewriteRule таких условий может быть одна и более или не быть вовсе.

Синтаксис инструкции

    RewriteCond testString condPattern [flags],
 

где
testString — строка, может содержать такие дополнительные конструкции:
  — ссылки на части шаблона текущей инструкции RewriteRule в виде $N (0 <= N <= 9). Параметр от $1 дo $9 обеспечивает доступ к сгруппированным частям шаблона RewriteRule, который подлежит дополнительной проверке. Величина $0 дает доступ ко всей строке шаблона.
  — ссылки на части шаблона предыдущей инструкции RewriteCond в виде %N (0 <= N <= 9). Параметр от %1 дo %9 обеспечивает доступ к сгруппированным частям шаблона RewriteCond из текущего набора условий. %0 дает доступ ко всей строке шаблона.
  — RewriteMap расширения в форме ${mapname:key|default}.
  — переменные сервера в форме %{ NAME_OF_VARIABLE }, где NAME_OF_VARIABLE могут быть строками из списка, приведенного в конце статьи.
  condPattern — шаблон условия — это регулярное выражение, результат которого применяется к текущему экземпляру строки testString, которая должна быть предварительно вычислена, перед как сравнить ее с condPattern. Перед условием возможно использование знака отрицания(без кавычек) «!» для указания неравенства шаблону. Кроме правил регулярного выражения здесь можно дополнительно применять:

  • ‘<condPattern’ — лексикографически предшествует
  • ‘>condPattern’ — лексикографически следует
  • ‘=condPattern’ — лексикографически равно
  • ‘<=CondPattern’ — лексикографически меньше или равно
  • ‘>=CondPattern’ — лексикографически больше или равно
  • ‘-d’ — проверяет, является ли TestString путем к ресурсу, проверяет существует ли такой и является ли каталогом
  • ‘-f’ — проверяет, является ли TestString путем к ресурсу, проверяет существует ли такой файл
  • ‘-s’ — проверяет, является ли TestString путем к ресурсу, существует ли и больше ли нуля размер файла.

Это далеко не полный перечень дополнений, кому интересно, ищите в Интернете, мы же можем предложить ссылку на первоисточник(en), где приведен полный список.
Примечание. Лексикографический порядок — способ упорядочивания (в данном случае строк) на основе сравнения входящих символов.
[flags] — специальный флаг, необязательный параметр для дополнительного управления, представляет собой список следующих символов, разделенных запятой:

  • ‘nocase|NC’ — (no case), флаг предписывает производить проверку без учета регистра символов в строках TestString и CondPattern, т.е. различие между ‘A-Z’ и ‘a-z’ игнорируются, действие на файловую систему и другие ресурсы не распространяется.
  • ‘ornext|OR’ — (or next condition) используется для упрощения условий проверки, например,

Пример использования флага [OR].

RewriteCond %{REMOTE_HOST} =host1 [OR]
RewriteCond %{REMOTE_HOST} =host2 [OR]
RewriteCond %{REMOTE_HOST} =host3
RewriteRule …

Без флага [OR] пару условие/правило пришлось бы приводить трижды, т.е. флаг позволяет заменить AND для пары правило + условие на более простое правило RewriteRule и логическое ИЛИ условий RewriteCond.
Кроме того, все проверки можно предварять знаком логического отрицания «!», т.е. возможно инвертирование результата проверки условия.

К списку инструкций сложного редиректа.

Инструкция RewriteBase

Инструкция явно задает базовый URL для перезаписи каталогов.
Синтаксис инструкции

RewriteBase URL-path,

где
URL-path — базовый URL для подстановки в относительные пути перенаправляемых запросов.

После всех преобразований добавляется слева к локальному конечному адресу для создания полного пути к требуемому ресурсу.
Пример использования инструкции.

<IfModule mod_rewrite.c>
    RewriteBase /
</IfModule>

К списку инструкций сложного редиректа.

Инструкция RewriteEngine

Синтаксис инструкции.

RewriteEngine on|off

Инструкция разрешает/запрещает использование перенаправления на лету, по умолчанию установлена в off, не наследуется нижестоящими файлами .htaccess, поэтому при использовании сложного редиректа ее надо включать в каждом файле .htaccess. Инструкцию удобно использовать для запрета применения инструкций редиректа, вместо комментирования многих строк достаточно закомментировать только эту.
Пример использования инструкции.

<IfModule mod_rewrite.c>
    RewriteEngine On
</IfModule>

Инструкция RewriteOptions

Синтаксис инструкции

RewriteOptions options,

где
options — строка опций, может принимать следующие значения:

  •     inherit — опция позволяет наследовать инструкции родительского каталога + инструкции в текущем файле .htaccess.
  •     MaxRedirects=число — ограничивает максимальное число перенаправлений, опция эффективна для борьбы с зацикливанием.
  •     AllowAnyURI — когда разрешена, опция снимает ограничения на обрабатываемые адреса ресурсов. В целях безопасности рекомендуется опцию запрещать.
  •     MergeBase — опция позволяет копировать RewriteBase из того места, где его значение явно указано, в другие поддиректории или места, в которых инструкция явно не приведена.

Пример использования инструкции.

RewriteOptions inherit

К списку инструкций сложного редиректа.

Примеры инструкций редиректа

Пример1.

#редирект запросов с http://www.name.com на http://name.com
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www.name.com$ [NC]
RewriteRule (.*) http://name.com/$1 [R=301]
 

Пример2.

# редирект запроса на другой ресурс, если не найдена ссылка на текущем сайте
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !-U
RewriteRule (.*) http://www.site.ru/$1 [R]
 

Пример3.

# редирект с разных страниц (site.com/index.php и site.com/index.html) на единую site.com/
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.html\ HTTP/
RewriteRule ^index\.html$ http://site.com [R=301,L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTP/
RewriteRule ^index\.php$ http://site.com [R=301,L]
 

Пример4.

# защита изображений от скачивания
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://(.+\.)?vash-url\.com/ [NC]
RewriteCond %{HTTP_REFERER} !^$
#Заменяем путь к изображению на предупреждение
RewriteRule .*\.(jpe?g|gif|bmp|png)$ /images/stop_image.jpg [L]
 
Пример5.
 
#Запрет доступа к файлу .htaccess 
<Files .htaccess>
  order allow,deny
  deny from all
</Files>

К списку инструкций сложного редиректа.

Наименование переменнойНаименование переменной
DOCUMENT_ROOT
HTTP_USER_AGENT
HTTP_REFERER
HTTP_COOKIE
HTTP_FORWARDED
HTTP_HOST
HTTP_PROXY_CONNECTION
HTTP_ACCEPT
SERVER_ADMIN
SERVER_NAME
SERVER_ADDR
SERVER_PORT
SERVER_PROTOCOL
SERVER_SOFTWARE
API_VERSION
THE_REQUEST
REQUEST_URI
REQUEST_FILENAME
IS_SUBREQ
HTTPS
REQUEST_SCHEME
REMOTE_ADDR
CONN_REMOTE_ADDR
REMOTE_HOST
REMOTE_PORT
REMOTE_USER
REMOTE_IDENT
REQUEST_METHOD
SCRIPT_FILENAME
PATH_INFO
QUERY_STRING
AUTH_TYPE
TIME_YEAR
TIME_MON
TIME_DAY
TIME_HOUR
TIME_MIN
TIME_SEC
TIME_WDAY
TIME

К списку управляющих инструкций .htaccess