Полное руководство по mod_rewrite (часть 1): Как включить и как работает mod_rewrite

Оглавление. Полное руководство по mod_rewrite

1. Как включить и как работает mod_rewrite

1.1 Что такое mod_rewrite

1.2 Для чего нужен mod_rewrite / Что умеет mod_rewrite

1.3 Включение mod_rewrite

1.4 Журнал (логи) преобразований mod_rewrite

1.5 Директивы RewriteEngine и RewriteRule

1.6 Шаблон RewriteRule

1.7 Какая часть запроса проверяется на совпадение с Шаблоном?

1.8 Подстановка RewriteRule

1.9 Директива RewriteBase

1.10 Логика работы mod_rewrite

1.11 Тестирование правил mod_rewrite

2. Регулярные выражения mod_rewrite

3. Флаги RewriteRule

4. Директива RewriteCond

5. Частые случаи и примеры использования mod_rewrite

6. Продвинутые техники

7. Директива RewriteMap

8. Директива RewriteOptions, технические подробности, когда НЕ использовать mod_rewrite


Что такое mod_rewrite

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

Эта инструкция призвана это исправить: если вы совершенно не понимаете даже азов работы mod_rewrite, то это руководство поможет вам разобраться; если вы уже в общих чертах понимаете, как происходит поиск совпадений и формирование нового адреса, то эта инструкция поможет вам систематизировать ваши знания и узнать новые сложные или необычные примеры использования mod_rewrite.

mod_rewrite предоставляет возможность динамически изменять входящие URL-запросы, основываясь на правилах, использующих регулярные выражения. Это позволяет вам сопоставлять произвольные URL-адреса к вашей внутренней структуре URL любым способом. По умолчанию mod_rewrite сопоставляет URL-адрес пути к файловой системе. Однако он также может использоваться для перенаправления одного URL-адреса на другой URL-адрес или для вызова внутренней прокси передачи.

mod_rewrite предоставляет гибкий и мощный способ манипулирования URL-адресами, используя неограниченное количество правил. Каждое правило может иметь неограниченное количество прикреплённых условий правила, позволяя вам переписать URL на основе переменных сервера, переменных среды, заголовков HTTP, метки времени, запросы к внешним базам данных и различных других внутренних программ и обработчиков.

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

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

Для чего нужен mod_rewrite / Что умеет mod_rewrite

Слово «rewrite» в названии модуля буквально означает «перезапись». Эта «перезапись» относится к URL (адресу сайта, страницы, файла). Перезапись (преобразование) происходит между тем, что введено в строке браузера пользователя (фактически, отправлено на веб-сервер) и тем, что веб-сервер получит на самом деле.

Наглядным примером применения mod_rewrite являются ЧПУ (аббр. от «человекопонятный URL») — URL-путь, состоящий из понятных слов, вместо идентификаторов, и отражающий файловую структуру сайта. Например, вместо /c14/3/97/ или /index.php?cat=10&subcat=2&id=41 будет /product/phone/Samsung/.

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

Слеши (/) на веб-сервере разделяют вложенные подпапки. Но в случае с ЧПУ если в адресе страницы встречается строка /product/phone/Samsung/, то это не означает, что на веб-сайте действительно имеется папка product, в которой подпапка phone и в которой подпапка Samsung. Благодаря mod_rewrite строка вида /product/phone/Samsung/ перезаписывается в строку вида index.php?category=product&type=phone&brand=Samsung. Таким образом, пользователь набирает в веб-браузере, либо переходит по ссылке с удобным для его восприятия адресом, а веб-сервер получает данные в понятном для обработки виде, когда каждой переменной присваивается соответствующее значение и эти переменные передаются в скрипт веб-сервера для обработки, либо отображения информации.

Это очень популярное, но не единственное применение mod_rewrite. Этот модуль умеет делать перезапись на основе разных данных: к примеру, на основе типа браузера. Это позволяет показывать разные страницы в зависимости от типа браузера, IP адреса, языка пользователя, установленных кукиз и т.д.

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

mod_rewrite умеет запрещать доступ к определённым ресурсам, как по определённому условию, так и безусловно. Т.е. вы можете настроить контроль доступа, закрыв определённые страницы для всех пользователей, либо на основе их стран, языка, веб-браузера и т.д.

На самом деле – это не всё, что умеет mod_rewrite! И даже в этом мануале вы встретитесь с дополнительными примерами применения mod_rewrite.

Прежде чем мы перейдём к теории и практики использования mod_rewrite, нужно включить модуль mod_rewrite для веб-сервера, либо убедиться, что mod_rewrite уже включен. Если вы используетесь shared (совместным) хостингом, то у большинства хостеров этот модуль включен по умолчанию. Ниже показано, как включить этот модуль на своём собственном локальном (домашнем) сервере, либо веб-сервере на VPS.

Включение mod_rewrite

mod_rewrite – это опциональный (необязательный) модуль веб-сервера Apache, который по умолчанию отключён. Поэтому работу с mod_rewrite нужно начать с его включения в веб-сервере.

Начнём с небольшой теории. Правила mod_rewrite для преобразования URL можно описывать как в конфигурационном файле Apache apache2.conf (в некоторых системах называется httpd.conf), так и в файле .htaccess отдельно для каждой директории.

Поскольку для большинства ситуаций удобнее использовать именно .htaccess, то для работы mod_rewrite нам нужно:

  • включить непосредственно сам mod_rewrite
  • включить поддержку файлов .htaccess

Если вы используете Debian, Ubuntu, Linux Mint, Kali Linux то mod_rewrite можно включить следующей командой:

sudo a2enmod rewrite

Для включения поддержки файла .htaccess в конфигурационном файле Apache (/etc/apache2/apache2.conf или /etc/httpd/conf/httpd.conf или другое расположение в зависимости от дистрибутива) найдите группу строк:

<Directory /путь/до/папки/сайтов>
	Options Indexes FollowSymLinks
	AllowOverride None
	Require all granted
</Directory>

В Debian, Ubuntu, Linux Mint, Kali Linux эта группа строк выглядит так:

<Directory /var/www/>
	Options Indexes FollowSymLinks
	AllowOverride None
	Require all granted
</Directory>

В этой группе строк замените

AllowOverride None

на

AllowOverride All

После чего перезапустите веб-сервер (на некоторых дистрибутивах служба называется не apache2, а httpd):

sudo systemctl restart apache2

Если вы используете Apache в Windows, то для включения mod_rewrite в файле httpd.conf (C:\Server\bin\Apache24\conf\httpd.conf) найдите и раскомментируйте строку:

LoadModule rewrite_module modules/mod_rewrite.so

Для включения поддержки файла .htaccess в конфигурационном файле Apache httpd.conf (C:\Server\bin\Apache24\conf\httpd.conf) найдите группу строк:

<Directory /путь/до/папки/сайтов>
	Options Indexes FollowSymLinks
	AllowOverride None
	Require all granted
</Directory>

В Windows она может выглядеть так:

<Directory "c:/Server/data/htdocs/">
	Options Indexes FollowSymLinks
	AllowOverride None
	Require all granted
</Directory>

В этой группе строк замените

AllowOverride None

на

AllowOverride All

Чтобы любые изменения, сделанные в конфигурационном файле Apache, вступили в силу, нужно перезапустить сервер.

Если вы решили для использования mod_rewrite вносить изменения в конфигурационный файл Apache, то не забывайте каждый раз после изменения правил перезапускать веб-сервер, чтобы эти изменения вступили в силу.

Также должна быть включена опция Options FollowSymLinks (по умолчанию она включена). Если FollowSymLinks отключено, то невозможно использовать движок перезаписи. Это ограничение продиктовано причинами безопасности.

Журнал (логи) преобразований mod_rewrite

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

Тема логов Apache сама по себе довольно объёмная, не будем на ней заострять внимание. Но необходимо упомянуть, что если вы работали с предыдущими версиями mod_rewrite и использовали директивы RewriteLog и RewriteLogLevel, то теперь их функциональность полностью заменена директивой LogLevel, которая настраивать логи всего веб-сервера и всех модулей.

По умолчанию LogLevel установлено показывать предупреждение, в конфигурационном файле Apache это строка:

LogLevel warn

Можно заменить эту строку на:

LogLevel error rewrite:trace2

Она означает, что для всего веб-сервера и остальных модулей настроен уровень журнала «error», т.е. показывать только ошибки и более важные сообщения, а для модуля mod_rewrite установлен уровень трассировки trace2.

mod_rewrite предлагает детальную запись его действий с уровней ведения журнала от trace1 до trace8. Уровень trace8 означает запись практически всех действий. Использование высоких уровней логов трассировки для mod_rewrite драматически замедлит ваш Apache HTTP сервер! Используйте уровень выше чем trace2 только для отладки!

Сообщения о работе mod_rewrite будут записываться в файл ошибок Apache (например, error.log). Чтобы из этого файла отфильтровать только строки, относящиеся к mod_rewrite, можно использовать поиск по «[rewrite:». К примеру, в Linux это можно делать примерно следующей командой:

tail -f /var/log/apache2/error.log | grep -F '[rewrite:'

Директивы RewriteEngine и RewriteRule

Модуль mod_rewrite использует несколько директив, и в этом руководстве мы рассмотрим их все. Но в каждом примере мы неизменно будем использовать две главные директивы, это RewriteEngine и RewriteRule. Первая директива, в виде

RewriteEngine on

просто включает использование mod_rewrite в файле .htaccess.

Значение директивы можно установить на off:

RewriteEngine off

В этом случае правила, которые следуют после отключения RewriteEngine off, не будут задействованы. Отключение RewriteEngine можно использовать вместо удаления или комментирования строк с правилами RewriteRule.

Конфигурации перезаписи не наследуются виртуальными хостами. Это означает, что нужно иметь директиву RewriteEngine on для каждого виртуального хоста, на которым вы хотите использовать правила перезаписи.

А вторая директива RewriteRule является главной рабочей лошадкой этого модуля. Именно с её помощью мы будем устанавливать правила перезаписи.

Она используется следующим образом:

RewriteRule Шаблон Подстановка [флаги]

Шаблон – это то, что мы ищем в передаваемом URL.

Подстановка – это новая строка, которая передаётся веб-серверу в том случае, если в исходных данных найдено совпадение с Шаблоном.

[флаги] – это условные обозначения, задающие дополнительные действия или поведение при перезаписи. Они являются необязательными. Мы также рассмотрим флаги в этой инструкции.

Шаблон RewriteRule

В качестве Шаблона используется регулярное выражение, которое представляет собой способ описать текст, который считается подходящим (совпадающим с шаблоном). Шаблоны можно выразить словами, например, «все слова, которые начинаются с буквы A» или «каждый десятизначный телефонный номер» или «каждое предложение с двумя запятыми и без заглавных букв Q».

Польза регулярных выражений в том, что они позволяют, не перечисляя все возможные варианты (которых может быть бесконечно много), установить правила для каждого из этого возможного варианта, если исходный запрос удовлетворяет определённым требованиям.

Они позволяют описывать различные условия очень гибки способом например: все файлы .gif и .jpg в любой директории "images" можно записать как "/images/.*(jpg|gif)$".

Более подробно регулярным выражениемя (шаблонам) посвящена вся вторая часть данного руководства.

Какая часть запроса проверяется на совпадение с Шаблоном?

Как уже было сказано, регулярные выражения могут быть установлены для всего веб-сервера (контекст всего сервера) в файле httpd.conf; для отдельного виртуального хоста (контекст виртуального хоста) в блоках <VirtualHost>; и для отдельных директорий (папок) (контекст директорий) в файлах .htaccess и блоках <Directory>).

В контексте VirtualHost Шаблон первоначально проверяется на соответствие с частью URL после имени хоста (hostname) и номера порта и до строки запроса (т.е. к примеру "/app1/index.html"). Это (%-кодированный) URL-путь.

В контексте директорий (Directory и .htaccess), Шаблон проверяется на совпадение только с частью пути, к примеру, запрос "/app1/index.html" может привести к сравнению по "app1/index.html" или "index.html" в зависимости от того, где определено RewriteRule.

Путь до директории, где определено правило, отбрасывается из анализируемого запроса (вплоть до и включая конечный слэш). В конечном счёте, правилу для сравнения передаётся стока «ниже» папки, где определено правилов.

Если вам нужно искать совпадения в имени хоста, порту или строке запроса, используйте RewriteCond (эта директива будет рассмотрена в четвёртой части данного руководства) с переменными %{HTTP_HOST}, %{SERVER_PORT} или %{QUERY_STRING} соответственно.

Подстановка RewriteRule

Подстановка правила перезаписи – это строка, которая заменяет оригинальный URL-путь, который совпал с Шаблоном. В качестве подстановки может быть:

  • путь в файловой системе

Указывает местоположение в файловой системе ресурса, который будет доставлен клиенту. Подстановки обрабатываются как путь к файловой системе, когда правило настроено в контексте сервера (virtualhost), и первый компонент пути в подстановке существует в файловой системе.

  • URL-путь

Относительный DocumentRoot путь к ресурсу, который будет обслуживаться. Обратите внимание, что mod_rewrite пытается угадать, указали ли вы путь файловой системы или URL-путь, проверяя, существует ли первый сегмент пути в корне файловой системы. Например, если вы укажете строку Подстановки /www/file.html, это будет рассматриваться как путь URL-адреса, если директория с именем www не существует в корне вашей файловой системы (или в случае использования перезаписи в файле .htaccess относительно вашего корня документов), в последних случаях это будет рассматриваться как путь в файловой системе. Если вы хотите, чтобы другие директивы сопоставления URL (такие как Alias) применялись к результирующему URL-адресу, используйте флаг [PT], как описано в третьей части данного руководства.

  • Абсолютный URL

Если указан абсолютный URL, mod_rewrite проверяет, совпадает ли имя хоста с текущим хостом. Если да, то схема и имя хоста отбрасываются и результирующий путь трактуется как URL-путь. В противном случае, выполняется внешний редирект (перенаправление) для заданного URL. Для принудительного внешнего редиректа на текущий хост (чтобы запрашиваемая страница поменяла адрес на другую страницу этого же хоста), смотрите флаг [R], описанный далее.

  • — (чёрточка)

Чёрточка говорит о том, что не должна выполняться какая-либо подстановка (существующий путь должен быть пропущен нетронутым). Это используется когда нужно применить флаг (смотрите далее) без изменения пути.

В дополнении к простому тексту, строка Подстановки может включать:

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

Директива RewriteBase

Мы уже выяснили, что на совпадение проверяется только часть запроса – начиная от текущий папки и далее вложенные подпапки. Если Подстановкой, получившейся в результате перезаписи, является относительный путь, то чтобы найти этот ресурс, к полученному значению добавляется путь до текущей папки. Это является поведением по умолчанию, а директива RewriteBase позволяет изменить это поведение.

Директива RewriteBase определяет URL префикс, используемый для постановки перед относительным путём.

Обычно, эта директива не требуется. Но она нужна когда:

  • перед Подстановкой нужно добавить не исходный путь до текущей папки, а путь до другой папки, например, находящейся выше текущей;
  • при использовании флага [R] (который означает редирект, т.е. перенаправление) перед получившейся строкой Подстановки всегда ставится http://этот-хост[:этот-порт], использование директивы RewriteBase отменяет это правило и перед получившейся Подстановкой ставится путь, указанный с RewriteBase.

Логика работы mod_rewrite

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

Это так, но это не всё. Если указано несколько правил RewriteRule и, допустим, в запросе найдено совпадение с первым правилом и исходная строка запроса изменена в соответствии с этим правилом. Второму правилу передаётся не исходная строка запрос, а новая строка, получившаяся в результате обработки всеми предыдущими правилами. И также происходит ниже по цепочке.

Проверку по всем правилам можно назвать проходом (раундом, циклом). Если в данном раунде случилось хотя бы одно совпадение (сработало правило), то после завершения прохода начинается ещё один круг проверки по этим же самым правилам! Это неочевидно и мало где об этом говориться – поэтому обратите на это особое внимание. Т.е. на новый раунд передаётся уже изменённая строка запроса и именно она проходит оценку по всем правилам. И вновь: если сработало хотя бы одно правило, идёт заход на новый круг и т.д.

Это является поведением по умолчанию для mod_rewrite. Это поведение можно изменить несколькими флагами, о которых будет рассказано далее.

Тестирование правил mod_rewrite

Для тестов, на вашем веб-сервере в папке сайтов создайте новую папку mr, к примеру, на Windows это может быть каталог C:\Server\data\htdocs\mr\, а на Linux это /var/www/html/mr/

Поскольку я работаю с локальным, сервером, то у меня теперь эта папка доступна по адресу http://localhost/mr

В этой папке создайте файл index.html следующего содержания:

FILE: index.html

И создайте пустой файл .htaccess

Продолжение: «Полное руководство по mod_rewrite (часть 2): Регулярные выражения».

Рекомендуется Вам:

Добавить комментарий

Ваш e-mail не будет опубликован.