Модуль 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