Описываются инструкции сложного редиректа с использованием mod_rewrite модуля. Приведены актуальные примеры редиректа. Полученные знания будут достаточны для практического использования файла .htaccess в управлении web сервером.
Содержание
- Основы редиректа
- Основы регулярных выражений
Управляющие символы
Примеры использования управляющих символов - Основные инструкции редиректа
Правила использования инструкций - Примеры инструкций редиректа
- Список переменных, применяемых в .htaccess
Основы редиректа
Как видно из названия, сегодня речь пойдет о редиректе Apache. Думаю, администраторов и владельцев доменов он не раз выручал в различных ситуациях. Редирект позволяет мгновенно выполнять перенаправление трафика независимо от используемого протокола, CMS или фреймворка, ведь он работает на уровне веб-сервера. Да у меня и воображения не хватит, чтобы перечислить ситуации, когда работает эта палочка-выручалочка. Поэтому знание его принципов и правил будет совсем не лишним для многих.
Что вы узнаете сегодня? Сначала познакомитесь с основными правилами использования и синтаксисом инструкций, а в конце приведен ряд примеров для закрепления навыков их применения. Поскольку основой редиректа является использование регулярных выражений, ниже приведена небольшая шпаргалка по этому мощному инструменту.
Основы регулярных выражений
Управляющие символы
В регулярных выражениях допустимы любые печатные символы и пробел, при этом часть символов, кроме обычного отображения, может использоваться в качестве управляющих. В частности:
- символ ^ обозначает начало строки;
- символ $ обозначает конец строки;
- круглые скобки () используются для выделения группы символов. Такие группы имеют порядковый номер по мере их появления. По этому номеру к ним можно в дальнейшем обратиться;
- Квадратные скобки [] для указания любого одного символа из перечисленных внутри скобок. Например, [абвг], набор символов можно указывать через дефис, например, предыдущий перечень будет выглядеть [а-г];
- Квадратные скобки с символом карет в начале [^] используются для перечисления недопустимых символов, например, [^абвг] будет соответствовать любому одному символу, кроме a,б,в,г;
- символ | используется в значении ИЛИ;
- если управляющий символ надо использовать в качестве обычного, перед ним ставится обратный слеш, например, выражение \. — позволит отобразить точку;
- символ # означает начало комментариев;
- символ . обозначает любой символ, кроме символа новой строки;
- Символ ? означает, что предшествующее выражение может присутствовать 0 или 1 раз;
- Символ * означает, что предшествующее выражение, символ или группа символов(в круглых скобках), может как отсутствовать, так и присутствовать неограниченное число раз подряд, т.е., 0 или N раз;
- символ + означает, что предшествующий символ или группа символов должен присутствовать хотя бы один раз, т.е., 1 или N раз;
- символ ! используется как логическое отрицание(инвертирование) в директивах
RewriteCond. Ставится перед строкой условия; - в регулярных выражениях широко используются переменные, которые представляют собой выражение вида
%{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
Синтаксис
где
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 таких условий может быть одна и более или не быть вовсе.
Синтаксис инструкции
где
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 для перезаписи каталогов.
Синтаксис инструкции
где
URL-path — базовый URL для подстановки в относительные пути перенаправляемых запросов.
После всех преобразований URL-path добавляется слева к локальному конечному адресу для создания полного пути к требуемому ресурсу.
Пример использования инструкции.
RewriteBase /
</IfModule>
К списку инструкций сложного редиректа.
Инструкция RewriteEngine
Синтаксис инструкции.
Инструкция разрешает/запрещает использование перенаправления на лету, по умолчанию установлена в off, не наследуется нижестоящими файлами .htaccess, поэтому при использовании сложного редиректа ее надо включать в каждом файле .htaccess. Инструкцию удобно использовать для запрета применения инструкций редиректа, вместо комментирования многих строк достаточно закомментировать только эту.
Пример использования инструкции.
RewriteEngine On
</IfModule>
Инструкция RewriteOptions
Синтаксис инструкции
где
options — строка опций, может принимать следующие значения:
- inherit — опция позволяет наследовать инструкции родительского каталога + инструкции в текущем файле .htaccess.
- MaxRedirects=число — ограничивает максимальное число перенаправлений, опция эффективна для борьбы с зацикливанием.
- AllowAnyURI — когда разрешена, опция снимает ограничения на обрабатываемые адреса ресурсов. В целях безопасности рекомендуется опцию запрещать.
- MergeBase — опция позволяет копировать RewriteBase из того места, где его значение явно указано, в другие поддиректории или места, в которых инструкция явно не приведена.
Пример использования инструкции.
К списку инструкций сложного редиректа.
Примеры инструкций редиректа
Пример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]
Запрет доступа к файлу .htaccess<Files .htaccess>
order allow,deny
deny from all
</Files>
К списку инструкций сложного редиректа.
Список переменных, применяемых в .htaccess
Ниже в таблице приведен список некоторых переменных, применяемых в инструкциях.
| Наименование | Описание | Наименование | Описание |
|---|---|---|---|
| DOCUMENT_ROOT | Путь к корневой папке сайта | REQUEST_METHOD | HTTP-метод входящего запроса (например, GET ) |
| HTTP_USER_AGENT | Информация о типе и версии браузера и операционной системы посетителя | REMOTE_ADDR | IP-адрес клиента |
| HTTP_REFERER | Адрес страницы, с которой пользователь перешел на текущую | REMOTE_HOST | Адрес посетителя , например, webdesign.com |
| HTTP_COOKIE | Список cookie, передаваемый браузером | REMOTE_PORT | Порт удаленного хоста (2.4.26 и новее) |
| HTTP_FORWARDED | IP-адрес прокси-сервера или сервера балансировки нагрузки | REMOTE_USER | Имя удаленного пользователя без хоста |
| HTTP_HOST | Адрес сервера, например, google.com | REMOTE_IDENT | Имя удаленного пользователя в формате имя.хост |
| API_VERSION | Возвращает версию API-модуля Apache | AUTH_TYPE | Тип используемой аутентификации |
| HTTP_ACCEPT | Представлены предпочтения клиента по типу документа | SCRIPT_FILENAME | Тоже, что и REQUEST_FILENAME |
| SERVER_ADMIN | Адрес электронной почты администратора сайта. | PATH_INFO | Содержит путь, стоящий после имени скрипта до строки запроса |
| SERVER_NAME | Адрес сервера, например, google.com | QUERY_STRING | Подстрока запроса в адресе |
| SERVER_ADDR | IP-адрес хоста, на котором размещен документ. | TIME | Дата обработки запроса в виде ГодМесяцДеньЧасМинутаСекунда без разделителей (20250127224332) |
| SERVER_PORT | Порт хоста, используемый для соединения | TIME_YEAR | Год в дате обработки запроса |
| SERVER_PROTOCOL | Протокол взаимодействия с клиентом, например'HTTP/1.0' | TIME_MON | Месяц в дате обработки запроса от 1 до 12 |
| SERVER_SIGNATURE | Строка, содержащая версию сервера и имя виртуального хоста, которые добавляются к генерируемым сервером страницам, если включено. | TIME_DAY | День обработки запроса от 1 до 31 |
| SERVER_SOFTWARE | Программное обеспечение установленное на сервере. Например, для Apache возвращается номер его версии, номер версии PHP | TIME_HOUR | Час даты обработки запроса |
| REQUEST_SCHEME | Часть схемы URI запроса | TIME_MIN | Минута даты обработки запроса |
| THE_REQUEST | Полная строка запроса (например, » GET /index.html HTTP/1.1 » ) | TIME_SEC | Секунда даты обработки запроса |
| REQUEST_URI | Адрес запрашиваемого документа, например, для https://wildpark.webdesignstudio1.net/index.html вернется значение index.html | TIME_WDAY | День недели обработки запроса от 0 до 6 |
| REQUEST_FILENAME | Полный путь к файлу или скрипту в файловой системе сервера | SCRIPT_NAME | Содержит путь к текущему исполняемому скрипту |
| IS_SUBREQ | Возвращает «true», если запрос выполняется в текущий момент как подзапрос, «false» в противном случае. | SCRIPT_USER | Имя пользователя владельца скрипта |
| HTTPS | «on» или «off» в зависимости от протокола | SCRIPT_GROUP | Имя группы скрипта |
