Модуль mod_rewrite сервера Apache
Модуль mod_rewrite веб сервера Apache используется для преобразования URL адресов. С его помощью можно настраивать редиректы, изменять URL адреса, блокировать доступ и т.д. По умолчанию этот модуль выключен, для того что бы его включить, в .htaccess необходимо добавить следующие директивы:
RewriteEngine On RewriteBase /
RewriteEngine On— директива включает модуль.RewriteBase— указывает путь от корня сайта до файла.htaccess. Если.htaccessлежит в корне, то указывать этот параметр нужно как в примере, если во внутреннем каталоге, то указываем путь к этому каталогу, например/images/.
Если .htaccess лежит в корне, то директиву RewriteBase можно опустить.
Работа модуля основана на наборе правил и условий, согласно которым производится преобразование. При получении запроса, Apache передает в mod_rewrite путь к файлу начиная от того места, где находится файл .htaccess, остальная часть пути обрезается. Если поступил запрос
http://server.com/some/path/file.html
а .htaccess лежит в корне, то в mod_rewrite попадет some/path/file.html (без слеша в начале). Если .htaccess лежит в директории /some/, то в mod_rewrite попадет path/file.html.
Далее mod_rewrite анализирует правила в .htaccess и действует согласно этих правил. Стоит знать, что mod_rewrite работает не со ссылками и не с URL адресами, а с обычными строками. То есть адрес, который нужно преобразовать, передается mod_rewrite как обычная строка, и эту строку можно преобразовать как угодно. Для построения правил используются две директивы, RewriteCond и RewriteRule.
- Директива
RewriteCond— здесь определяются условия, при которых сработает правило преобразованияRewriteRule. Если условие вRewriteCondвыполнено, выполняется правило вRewriteRule. Таких условий перед правиломRewriteRuleможет быть неограниченное количество.RewriteCondне является обязательной директивой для создания правила преобразования и может отсутствовать.
- Директива
RewriteRule— здесь уже указывается само правило для преобразования, которое для конкретного преобразования должно быть единственным.
Директива RewriteRule
Синтаксис директивы RewriteRule:
RewriteRule Шаблон Подстановка [Флаги]
Шаблон— условие, выполнение которого запускает исполнение правила;Подстановка— правило изменения (преобразования) URL;[Флаги]— дополняют преобразование URL.
Примеры:
# Преобразуем URL www.server.com/articles/123/ в # URL www.server.com/index.php?show=article&id=123 RewriteRule ^articles/(\d+)/$ index.php?show=article&id=$1 [L]
# Запрет посещений веб-сайта для робота поисковой системы # Google (при вызове возвращает ошибку 403 Forbidden) RewriteCond %{USER_AGENT} Googlebot # Дефис означает, что преобразование URL не требуется RewriteRule .* - [F]
# Исправление ошибки при наборе адреса веб-страницы пользователем RewriteRule ^(.*)\.htm$ $1.html [R=301]
Некоторые флаги RewriteRule:
[NC]— Это делаетШаблоннечувствительным к регистру, когдаШаблонприменяется к текущему URL.[QSA]— Добавить строку запроса из исходного URL к строке запроса, созданной правилами перезаписи.[L]— Остановить процесс преобразования на этом месте и не применять больше никаких правил преобразований.[N]— Перезапустить процесс преобразований (начав с первого правила). В этом случае URL снова сопоставляется неким условиям, но не оригинальный URL, а URL вышедший из последнего правила преобразования.[F]— Сервер возвращает браузеру ошибку с кодом 403.[R]— Редирект с кодом ответа браузеру 302 (временно перемещен).[R=code]— Редирект с кодом ответа браузеруcode.
Флаг QSA (Query String Append)
Строкой запроса является часть запрашиваемого адреса, которая следует после символа знак вопроса. К примеру, в запросе
/some/path/index.php?param=value
строкой запроса является выделенная красным часть.
Когда заменяющий URI (полученный после применения правил перезаписи) содержит строку запроса, поведение по умолчанию RewriteRule — отбросить исходную строку запроса и заменить её сгенерированной новой. Использование флага [QSA] приводит к объединению строк запроса.
# Преобразуем URL www.server.com/articles/123/ в # URL www.server.com/index.php?show=article&id=123 RewriteRule ^articles/(\d+)/$ /index.php?show=article&id=$1 [QSA,L]
С флагом [QSA], запрос
/articles/123/?param=value
будет преобразован в
/index.php?show=article&id=123¶m=value
Без флага [QSA], этот же самый запрос будет преобразован в
/index.php?show=article&id=123
То есть, существующая строка запроса будет отброшена.
Директива RewriteCond
Синтаксис директивы RewriteCond:
RewriteCond СравниваемаяСтрока Условие [Флаги]
СравниваемаяСтрока— строка, которая будет проверятся на соответствие выражению, указанному в параметреУсловие.Условие— это логическое выражение, по которому проверяется параметрСравниваемаяСтрока. Часто вУсловиеприменяют регулярные выражения.[Флаги]— позволяют задать дополнительные опции, например, можно установить логику объединения правилRewriteCondчерез логическое И[AND](по умолчанию) или через логическое ИЛИ[OR]. Или, будет ли сравнение в условииRewriteCondвыполнятся с учетом регистра или без учета регистра.
Пример нескольких директив RewriteCond, объединенных через логическое И [AND] (по умолчанию):
# одна точка входа, все запросы (кроме файлов и директорий) на /index.php RewriteCond $1 !=favicon.ico RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule (.*) index.php
Несмотря на то, что директива RewriteCond стоит выше, чем правило RewriteRule, mod_rewrite сначала проверяет строку на соответствие с шаблоном в RewriteRule, и если строка совпадает с шаблоном, он смотрит на указанные выше условия в RewriteCond. Если условия тоже совпадают, происходит преобразование согласно правилу RewriteRule.
СравниваемаяСтрока может, к примеру, содержать часть или весь URL. Подставить в параметр СравниваемаяСтрока часть URL можно при помощи переменных подстановки ($1, $2, $3), которые были созданы в соответствующем RewriteRule. Также параметр СравниваемаяСтрока может содержать различные переменные из окружения сервера Apache: %{REQUEST_URI}, %{HTTP_HOST}, %{QUERY_STRING} и т.д.
Условие может содержать специальные символы:
-d— проверка, что директория существует;-f— проверка, что файл существует.
Дополнительно, перед условием, допускается использование логических символов:
!Условие— инвертирование значения, т.е. сравниваемая строка должна не соответствовать шаблону условия;=Условие—Условиесчитается простой строкой и лексически сравнивается сСравниваемаяСтрока. Истинно, если эти две строки полностью одинаковы (символ в символ). ЕслиУсловиеимеет вид""— это сравниваетСравниваемаяСтрокас пустой строкой.
Некоторые флаги RewriteCond:
[NC](отNo Case) — Регистр не имеет значения, как вСравниваемаяСтрокатак и вУсловие. Этот флаг эффективен только для сравнений междуСравниваемаяСтрокаиУсловие, он не работает при проверках в файловой системе.[OR]— Логическое ИЛИ. Используется, когда перед директивойRewriteRuleнаходится несколько директивRewriteCondи правило вRewriteRuleдолжно быть выполнено при совпадении любогоRewriteCond.[AND]— Логическое И. Используется, когда перед директивойRewriteRuleнаходится несколько директивRewriteCondи правило вRewriteRuleдолжно быть выполнено при совпадении всехRewriteCond. Этот флаг используется по умолчанию, так что его можно опускать.
Регулярные выражения
Текст
.— Любой одиночный символ[chars]— Класс символов: один из символов[^chars]— Класс символов: ни один из символов(text1|text2)— Альтернатива:text1илиtext2
Кванторы
?— 0 или 1 из предшествующего текста*— 0 или больше из предшествующего текста+— 1 или больше из предшествующего текста
Группировка
(text)— Группировка текста (для установки границ альтернативы или для создания переменных$1,$2,$3или%1,%2,%3)
Маркеры
^ — Маркер начала строки$ — Маркер конца строкиЭкранирование
\char— экранирование конкретного символа (к примеру, для указания символов.[]()и т.д.)
Переменные окружения сервера
Если запрашивается документ:
http://www.host16.ru/some/path/index.php?param=value
то переменные окружения сервера будут:
| Переменная | Описание | Значение |
|---|---|---|
DOCUMENT_ROOT |
Путь к корневой папке сайта. Зависит от операционной системы сервера и используемого программного обеспечения. | D:/work/localhost16/www |
HTTP_ACCEPT |
Типы файлов, которые способен принять браузер. В качестве значения возвращается список поддерживаемых MIME-типов разделенных между собой запятой. | text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, image/apng, */*;q=0.8 |
HTTP_HOST |
Доменное имя сайта. Переменная вернёт тот адрес сайта, который указан в адресной строке браузера. | www.host16.ru |
HTTP_REFERER |
Адрес страницы, с которой пользователь перешел на данный сайт, он еще называется реферер. | |
HTTP_USER_AGENT |
Идентификатор используемого браузера и операционной системы. В качестве значения возвращается строка, содержащая ключевые слова. | Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36 |
QUERY_STRING |
Запрос, который указан в адресной строке после вопросительного знака. | param=value |
REMOTE_ADDR |
IP-адрес посетителя сайта | 127.0.0.1 |
REQUEST_FILENAME |
Полный путь в файловой системе сервера к файлу или скрипту. По факту содержит те же данные, что и SCRIPT_FILENAME. |
D:/work/localhost16/www/some/path/index.php |
REQUEST_METHOD |
Метод отправки данных на сервер, по умолчанию применяется метод GET. | GET |
REQUEST_URI |
Адрес запрашиваемого документа, отсчёт ведётся от корня сайта. | /some/path/index.php?param=value |
SERVER_PROTOCOL |
Протокол для получения и отправки данных. | HTTP/1.1 |
SCRIPT_NAME |
Путь к текущему исполняемому скрипту. | /some/path/index.php |
SCRIPT_FILENAME |
Абсолютный путь к исполняемому скрипту. | D:/work/localhost16/www/some/path/index.php |
SERVER_NAME |
Имя сервера. | www.host16.ru |
THE_REQUEST |
Полная строка HTTP запроса, отправленная браузером серверу. Она не включает какие-либо дополнительные заголовки, отправляемые браузером. | GET /some/path/index.php?param=value HTTP/1.1 |
Переменные подстановки RewriteCond и RewriteRule
Если в директивах RewriteCond и/или RewriteRule часть символов заключить в круглые скобки, то можно обращаться к содержимому в этих скобках через переменные $1, $2, $3 и/или %1, %2, %3:
$n— позволяет использовать группу символов из шаблона директивыRewriteRule;%n— позволяет использовать группу символов из шаблона директивыRewriteCond.
# Редирект с адреса с www на адрес без www RewriteCond %{HTTP_HOST} ^www\.server\.com$ [NC] RewriteRule ^(.*)$ http://server.com/$1 [R=301,L]
# Редирект с адреса с www на адрес без www RewriteCond %{HTTP_HOST} ^www\.(.*) [NC] RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
# Редирект с адреса без www на адрес с www RewriteCond %{HTTP_HOST} ^server\.com$ [NC] RewriteRule ^(.*)$ http://www.server.com/$1 [R=301,L]
# Редирект с адреса без www на адрес с www RewriteCond %{HTTP_HOST} !^www\.(.*) [NC] RewriteRule ^(.*)$ http://www.%1/$1 [R=301,L]
Примеры
# запретить использование ссылок на изображения другими сайтами RewriteCond %{HTTP_REFERER} !^$ RewriteCond %{HTTP_REFERER} !^http://(www\.)?server\.com/.*$ [NC] RewriteRule .+\.(gif|jpe?g|png)$ - [F]
# перенаправление с HTTP на HTTPS RewriteCond %{HTTPS} =off RewriteRule (.*) https://%{SERVER_NAME}/$1 [R=301,L]
# перенаправление с HTTP на HTTPS RewriteCond %{SERVER_PORT} !=443 RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
# запрет доступа к файлу .htaccess RewriteRule ^\.htaccess$ - [F]
# запрет доступа к сайту поисковому роботу EmailSiphon RewriteCond %{HTTP_USER_AGENT} ^EmailSiphon RewriteRule .* - [F]
# запрет доступа к сайту с ip-адреса 212.37.64.10 RewriteCond %{REMOTE_ADDR} ^212.37.64.10$ RewriteRule .* - [F]
# редирект страниц со слэшем в конце на страницы без слэша, # чтобы исключить дублирвание; например /about/ => /about RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} ^(.+)/$ RewriteRule ^(.+)/$ $1 [R=301,L]
# редирект страниц без слэша в конце на страницы со слэшом, # чтобы исключить дублирвание; например /about => /about/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_URI} !(.*)/$ RewriteRule ^(.*[^/])$ $1/ [R=301,L]
Поиск: .htaccess • Apache • RegExp • SEO • URL • Web-разработка • ЧПУ • Шаблон • mod_rewrite • RewriteEngine • RewriteBase • RewriteCond • RewriteRule