Академия mod_rewrite. Урок 3: RewriteCond и переменные %{...}
RewriteRule сам по себе смотрит только на путь запроса. Чтобы проверить протокол, хост, метод, заголовки, IP, наличие файла — нужен RewriteCond. Это условие, которое стоит перед правилом и управляет тем, сработает ли оно. В уроке разберём синтаксис, серверные переменные и практические примеры.
Урок 3 из 5 · ← предыдущий | следующий → · оглавление курса
Зачем нужен RewriteCond
RewriteRule матчит только путь запроса (например, blog/5). Но часто нужно проверить что-то ещё:
- «Выполнить редирект, только если запрос по HTTP, а не HTTPS»
- «Сработать, только если хост начинается с
www.» - «Заблокировать, только если User-Agent содержит "bot"»
- «Перезаписать в index.php, только если файл физически не существует»
Всё это — задача RewriteCond.
Синтаксис RewriteCond
Синтаксис: RewriteCond ТестоваяСтрока Паттерн [Флаги].
RewriteCondставится передRewriteRuleи действует только на ближайший следующийRewriteRule.- Несколько
RewriteCondподряд — все должны быть истинны (логическое И). - Флаг
[OR]на условии объединяет его со следующим через «ИЛИ». - Флаг
[NC]— сравнение без учёта регистра. - Ведущий
!перед паттерном — инверсия: «не совпадает».
RewriteEngine On # Одно условие перед правилом: RewriteCond %{HTTPS} off RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] # Два условия (оба должны быть истинны): RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^ index.php [L]
Часто используемые переменные
Серверные переменные записываются в формате %{ИМЯ}:
%{HTTP_HOST}— хост из запроса:example.comилиwww.example.com.%{HTTPS}—on, если запрос по HTTPS, иначеoff. За reverse-proxy или CDN может всегда бытьoff— тогда используйте%{HTTP:X-Forwarded-Proto}.%{REQUEST_URI}— путь запроса (/blog/5), без строки запроса. Меняется при внутренней перезаписи.%{QUERY_STRING}— строка запроса (то, что после?). Важно: query string НЕ входит в паттернRewriteRule— её можно проверить только черезRewriteCond %{QUERY_STRING}.%{REQUEST_METHOD}—GET,POST,HEAD, …%{REMOTE_ADDR}— IP-адрес клиента.%{HTTP_USER_AGENT}— строка User-Agent браузера или бота.%{HTTP_REFERER}— заголовок Referer.%{HTTP:X-Forwarded-Proto}— любой произвольный заголовок (здесь:X-Forwarded-Proto).%{REQUEST_FILENAME}— полный путь на диске, соответствующий запросу. Используется с проверками-f/-d.%{THE_REQUEST}— полная первая строка HTTP-запроса (GET /blog/5 HTTP/1.1). Не меняется при внутренних перезаписях — полезно для защиты от петель редиректов.
Специальные проверки: -f, -d, -s, -l
Вместо паттерна-регулярки в RewriteCond можно использовать проверки файловой системы:
-f— запрошенный путь соответствует существующему обычному файлу.-d— соответствует существующему каталогу.-s— файл существует и непустой (size > 0).-l— символическая ссылка.- Ведущий
!— инверсия:!-f= «файл НЕ существует».
Лексикографические сравнения (вместо regex): =строка (точное равенство), <строка, >строка. Числовые (Apache 2.4): -eq, -lt, -gt и др.
Бэкрефы %1 из условий
Группы захвата ( ) в паттерне RewriteCond доступны как %1, %2, … в подстановке следующего RewriteRule и в последующих RewriteCond.
Это позволяет извлечь часть значения переменной. Классический пример — www-канонизация: перенаправить www.example.com на example.com, захватив основной домен:
RewriteEngine On RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]
Здесь %1 — всё, что захватила группа (.+) из хоста, то есть домен без www.. %{REQUEST_URI} — исходный путь (добавляем в подстановку, чтобы не потерять).
Практические примеры
HTTPS-редирект:
RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
За прокси/CDN используйте: RewriteCond %{HTTP:X-Forwarded-Proto} !https.
Режим обслуживания для всех, кроме своего IP:
RewriteEngine On RewriteCond %{REMOTE_ADDR} !^192\.168\.1\.100$ RewriteCond %{REQUEST_URI} !^/maintenance\.html$ RewriteRule ^ /maintenance.html [R=302,L]
Блокировка по User-Agent:
RewriteEngine On RewriteCond %{HTTP_USER_AGENT} (scrapy|wget|python-requests) [NC] RewriteRule ^ - [F,L]
Попробуй сам
Тестер RewriteRule поддерживает RewriteCond — вставьте блок с условиями и заполните поля «переменные сервера» (хост, HTTPS, User-Agent). Посмотрите в трассировке, какие условия прошли и почему.
Упражнения
-
Напишите правило, которое делает редирект http → https, и проверьте его в тестере RewriteRule.
Подсказка:RewriteCond %{HTTPS} offперед правилом. -
Напишите правило, которое редиректит на без-www, но только если хост начинается на
www..
Подсказка:RewriteCond %{HTTP_HOST} ^www\.(.+)$и%1в подстановке.
Проверьте в тестере RewriteRule. -
Напишите правило режима обслуживания: всем отдаётся
/maintenance.html, кроме своего IP (например,10.0.0.1).
Подсказка: дваRewriteCond— на IP и на URL самой страницы обслуживания (чтобы не зациклиться). -
Почему
RewriteCond %{QUERY_STRING}иногда обязателен? Назовите ситуацию, когда без него не обойтись.
Подсказка: паттернRewriteRuleне видит строку запроса.
Что дальше
В уроке 4 погрузимся в регулярные выражения: якоря, классы символов, кванторы, группы захвата и готовые паттерны для типовых задач. Всё это с практикой в тестере regex.