О сайте | Карта сайта | Календарь сайта | Содержание
www.shtogrin.com  
Главная  //  Библиотека  //  Веб  //  Модуль mod_rewrite  //  Документация mod_rewrite  //  Директива RewriteRule

Директива RewriteRule

Описание: Определяет правила для механизма преобразований
Синтаксис: RewriteRule Шаблон-Подстановка
Значение по умолчанию: None
Контекст: server config, virtual host, directory .htaccess
Разрешение: FileInfo
Статус: Расширение
Модуль: mod_rewrite
Совместимость: Флаг cookie доступен в Apache 2.0.40 и более поздних.

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

Шаблон это perl совместимое регулярное выражение которое применяется к текущему URL. Здесь под текущим подразумевается значение URL когда применяется это правило. Этот URL не обязательно совпадает с первоначально запрошенным URL, потому что любое количество правил возможно уже были применены к нему и соответственно преобразовали его.

Некоторые указания по синтаксису регулярных выражений:

Текст:
  .           Любой одиночный символ
  [chars]     Класс символов: Один из символов
  [^chars]    Класс символов: Ни один из символов
  text1|text2 Альтернатива: text1 или text2

Кванторы (символы для обозначения количественных отношений):
  ?           0 или 1 из предшествующего текста
  *           0 или N из предшествующего текста (N > 0)
  +           1 или N из предшествующего текста (N > 1)

Группировка:
  (text)      Группировка текста
              (либо установка границ альтернативы или
              для создания обратных связей где N группа, которая 
              может быть использована в RHS директивы RewriteRule с $N)

Маркеры:
  ^           Маркер начала строки
  $           Маркер конца строки

Экранирование:
  \char       экранирование конкретного символа
              (к примеру для указания символов ".[]()" и т.д.)

Примечание

При использовании символа NOT (не) для инвертирования действия шаблона вы не можете иметь сгруппированные части групповых символов в шаблоне. Это невозможно потому что когда нет соответствия шаблону, для групп нет никакого содержимого. В результате, если используются шаблоны с отрицанием, вы не можете использовать $N в строках подстановок!

Подстановка в правиле преобразования это строка будет подставляться (или будет заменять) вместо оригинального URL, для которого есть совпадение Шаблону. Кроме простого текста вы можете использовать

  1. обратные связи $N на шаблоны в RewriteRule
  2. обратные связи %N на последний соответствующий шаблон в RewriteCond
  3. переменные сервера в качестве проверяемых строк в условиях правил (%{VARNAME})
  4. вызовы запросов к массиву (${mapname:key|default})

Обратные связи это $N (N=0..9) идентификаторы которые заменяются содержимым N-й группы подходящего Шаблона. Переменные сервера Это тоже самое что и Сравниваемая Строка директивы RewriteCond. Запросы к массиву пришли из директивы RewriteMap там они и объяснены. Эти три типа переменных рассматриваются в порядке, в котором они идут в вышеприведенном списке.

Как уже было упомянуто выше, все правила преобразований применяются с использованием Подстановки (в порядке, в котором они определены в конфигурационном файле). URL полностью заменяется Подстановкой и процесс преобразования идет до тех пор, пока не останется больше никаких правил, если только он не прерван специально, с помощью флага L см. ниже.

Существует специальная строка подстановки вида '-' которая означает: НЕТ подстановки! Звучит глупо? Нет, это полезно для правил преобразования которые только проверяют некоторые URL однако не производят подстановок, т.е., в связке с флагом C (цепочка) возможно иметь более чем один шаблон, применяемый перед проведением непосредственно самой подстановки.

Ещё одно замечание: Вы даже можете создавать URL, содержащие строку запроса, в строке подстановки. Просто используйте вопросительный знак внутри строки подстановки для указания того, следующее за ним содержимое должно быть преобразовано в QUERY_STRING (строку запроса). Когда вы хотите убрать существующую строку запроса, завершайте строку подстановки просто вопросительным знаком.

Примечание

Есть одна особенность: Когда вы предваряете поле подстановки строкой http://thishost[:thisport], mod_rewrite отрезает её автоматически. Это автоматическое усечение подразумеваемое при внешнем редиректе URL полезная и важная особенность при использовании в связке с запросами к массивам преобразований генерирующих имя хоста. Взгляните на первый пример, в разделе примеров ниже, чтобы понять это.

Помните

Безусловный внешний редирект на ваш собственный сервер не будет работать с префиксом http://thishost из-за этой особенности. Чтобы использовать такой саморедирект, Вы должны использовать флаг R(см. ниже).

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

[флаги]

в качестве третьего аргумента директивы RewriteRule. Флаги это разделённый запятыми, следующий список флагов:

  • 'redirect|R [=code]' (вызывает редирект)
    Префикс в Подстановке вида http://thishost[:thisport]/ (создающий новый URL из какого-либо URI) запускает внешний редирект (перенаправление). Если нет никакого кода в подстановке ответ будет с HTTP статусом 302 (ВРЕМЕННО ПЕРЕМЕЩЕН). Если вы хотите использовать другие коды ответов в диапазоне 300-400, просто напишите их в виде числа или используйте одно из следующих символических имён: temp (по умолчанию), permanent, seeother. Используйте это в директивах, которые должны преобразовывать некие виртуальные URL в реальные и возвращать их клиенту, например, преобразовывать /~ в /u/ или всегда добавлять слеш к /u/user, и т.д.

    Примечание: При использовании этого флага, убедитесь, что поле подстановки, это работающий URL! Если это не так, вы перенаправляете в никуда! И помните, что сам по себе этот флаг, только дополняет URL строкой http://thishost[:thisport]/, и процесс преобразования продолжается. Также, обычно вы хотите остановиться и сделать этот редирект немедленно. Для остановки процесса преобразования, вам также нужно написать флаг 'L'.

  • 'forbidden|F' (делает URL запрещенным)
    Это делает текущий URL запрещённым, например, клиенту немедленно отправляется ответ с HTTP статусом 403 (ЗАПРЕЩЕНО). Используйте этот флаг в сочетании с соответствующими RewriteConds для блокирования URL по некоторым критериям.
  • 'gone|G' (делает URL мёртвым )
    Этот флаг делает текущий URL мертвым , т.е., немедленно отправляется HTTP ответ со статусом 410 (GONE). Используйте этот флаг для маркировки мертвыми не существующие более страницы.
  • 'proxy|P' (вызывает прокси)
    Этот флаг помечает подстановочную часть как внутренний запрос прокси и немедленно (т.е., процесс преобразования здесь останавливается) пропускает его через прокси модуль. Вы должны убедиться, что строка подстановки это реальный URI (например, типично начинающийся с http://hostname), который может быть обработан прокси модулем Apache. Если это не так, вы получите ошибку от прокси модуля. Используйте этот флаг для того, чтобы добиться более мощной реализации директивы ProxyPass, интегрирующей некоторое содержимое на удаленных серверах, в пространство имён локального сервера.

    Примечание: Для того чтобы это использовать убедитесь что у вас есть работающий прокси модуль на вашем сервере Apache. Если вы не знаете этого проверьте есть ли в выводе httpd -l строчка mod_proxy.c. Если да, эти возможности доступны mod_rewrite. Если нет, то сначала вы должны пересобрать программу httpd с включенным прокси модулем.

  • 'last|L' (последнее правило)
    Остановить процесс преобразования на этом месте и не применять больше никаких правил преобразований. Это соответствует оператору last в Perl или оператору break в языке C. Используйте этот флаг для того, чтобы не преобразовывать текущий URL другими, следующими за этим, правилами преобразований. К примеру, используйте это для преобразования корневого URL из ('/') в реальный, например, '/e/www/'.
  • 'next|N' (следующий раунд)
    Перезапустить процесс преобразований (начав с первого правила). В этом случае URL снова сопоставляется неким условиям, но не оригинальный URL, а URL вышедший из последнего правила преобразования. Это соответствует оператору next в Perl или оператору continue из языка C. Используйте этот флаг для перезапуска процесса преобразований, т.е., безусловному переходу на начало цикла.
    Однако будьте осторожны, для того чтобы не сделать бесконечный цикл!
  • 'chain|C' (связь со следующим правилом)
    Этот флаг связывает текущее правило со следующим (которое, в свою очередь, может быть связано со следующим за ним, и т.д.). Это имеет следующий эффект: если есть соответствие правилу, процесс продолжается как обычно, т.е., флаг не производит никакого эффекта. Если правило не соответствует условию, все следующие, связанные правила, пропускаются. Например, используйте это для удаления .www части в конфигурационном правиле контекста каталога работающего когда вы разрешаете внешний редирект (где не должно быть .www !).
  • 'type|T=MIME-тип' (принудительно установить MIME тип)
    Принудительно установить MIME-тип целевого файла в MIME-тип. К примеру, это можно использовать для имитации mod_alias директивы ScriptAlias которая принудительно устанавливает для всех файлов внутри отображаемого каталога MIME тип равный application/x-httpd-cgi .
  • 'nosubreq|NS' (используется только в случае невнутреннего подзапроса)
    Этот флаг дает команду механизму преобразований пропустить директиву если текущий подзапрос является внутренним подзапросом. К примеру, внутренние подзапросы в Apache происходят тогда, когда mod_include пытается получить информацию о возможных файлах по умолчанию для каталогов (index.xxx). При подзапросах это не всегда полезно и даже иногда вызывает проблему в работе всего набора директив преобразований. Используйте этот флаг для исключения некоторых правил.

    Используйте следующее правило по своему усмотрению: всякий раз когда вы предваряете некоторые URL префиксом передавая их на обработку CGI-скрипту, велик шанс что вы напоретесь на проблемы (или даже на ненужные издержки) в случае применения подзапросов. В этих случаях, используйте этот флаг.

  • 'nocase|NC' (не учитывать регистр)
    Это делает Шаблон нечувствительным к регистру, т.е., нет различий между 'A-Z' и 'a-z' когда Шаблон применяется к текущему URL.
  • 'qsappend|QSA' (добавлять строку запроса)
    Этот флаг указывает механизму преобразований на добавление а не замену, строки запроса из URL к существующей, в строке подстановки. Используйте это когда вы хотите добавлять дополнительные данные в строку запроса с помощью директив преобразований.
  • 'noescape|NE' (не экранировать URI при выводе)
    Этот флаг не даёт mod_rewrite применять обычные правила экранирования URI к результату преобразования. Обычно, специальные символы (такие как '%', '$', ';', и так далее) будут экранированы их шестнадцатеричными подстановками ('%25', '%24', и '%3B', соответственно); этот флаг не дает это делать. Это позволяет символам процента появляться на выходе , как в

    RewriteRule /foo/(.*) /bar?arg=P1\%3d$1 [R,NE]

    для которого '/foo/zed' преобразовывалось бы в безопасный запрос '/bar?arg=P1=zed'.
  • 'passthrough|PT' (пропускать через следующий обработчик)
    Этот флаг даёт команду механизму преобразований устанавливать поле uri внутренней структуры request_rec равным полю filename. Этот флаг, просто лишь хитрый трюк, для того чтобы иметь возможность обработки вывода директив RewriteRule, директивами Alias, ScriptAlias, Redirect, и т.д. из других трансляторов URI-имя файла. Тривиальный пример для показа этой семантики: если вы хотите преобразовать /abc в /def с использованием механизма преобразований mod_rewrite и затем /def в /ghi с использованием mod_alias:

    RewriteRule ^/abc(.*) /def$1 [PT]
    Alias /def /ghi

    Если вы опустите флаг PT, mod_rewrite прекрасно сделает свою работу, т.е., он преобразует uri=/abc/... в filename=/def/... как должен делать полностью API-совместимый транслятор URI-имя файла. Затем настаёт очередь mod_alias пытающегося сделать переход URI-имя файла который и не будет работать.
  • 'skip|S=количество' (пропустить следующее правило(а))
    Этот флаг указывает механизму преобразований пропускать следующее количество правил в последовательности начинающейся с текущего правила. Используйте это для создания псевдо if-then-else конструкций: Последнее правило блока then будет skip=N где N количество правил блока else. (Это не то же самое что и флаг 'chain|C'!)
  • 'env|E=VAR:VAL' (установить переменную окружения)
    Присваивает переменной окружения VAR значение VAL, где VAL может содержать обратные связи $N и %N ссылающиеся на части регулярных выражений, которые будут раскрыты соответствующим образом. Вы можете использовать этот флаг более одного раза чтобы присвоить значение более чем одной переменной. Позже, эти переменные могут быть использованы во многих ситуациях, обычно в XSSI (через <!--#echo var="VAR"-->) или в CGI скриптах (например$ENV{'VAR'}). Кроме того, вы можете это использовать в следующем шаблоне RewriteCond через %{ENV:VAR}. Используйте это для удаления, но запоминания некоторой информации из URL.
  • 'cookie|CO=NAME:VAL:domain[:lifetime[:path]]' (записать cocookie)
    Записывает cookie клиенту. Имя cookie указывается в NAME а его значение в VAL. Поле domain это домен cookie, такой как например '.apache.org', опциональное lifetime это время жизни cookie в минутах, и опциональный path это путь cookie

Примечание

Никогда не забываёте что Шаблон применяется ко всему URL в конфигурационных файла сервера. Однако в конфигурационных файлах каталогов, префикс каталога (который всегда одинаков для конкретного каталога !), автоматически удаляется при соответствии шаблону и автоматически добавляется после завершения подстановки. Эта особенность, основа для многих видов преобразований, потому что без удаления префикса для родительского каталога тоже должно быть соответствие, что не всегда возможно.

Есть одно исключение: Если строка подстановки начинается с http:// в этом случае префикс каталога не добавляется и происходит либо внешний редирект либо пропускание через прокси (если используется флаг P!)!

Пример:

Мы хотим преобразовать URL вида

/ Language /~ Realname /.../ File

в

/u/ Username /.../ File . Language

Мы берем файл, содержащий ассоциативный массив для преобразований, приведённый выше и сохраняем его под именем /path/to/file/map.txt. Затем, нам нужно только добавить следующие строчки в конфигурационный файл сервера Apache:

RewriteLog   /path/to/file/rewrite.log
RewriteMap   real-to-user               txt:/path/to/file/map.txt
RewriteRule  ^/([^/]+)/~([^/]+)/(.*)$   /u/${real-to-user:$2|nobody}/$3.$1

22.02.2007


2006-2024, Roman Shtogrin