© Discript 2018 - 2022

Что такое rewriterule

Содержание:

  1. Немного теории
  2. Что такое mod_rewrite
  3. Как работает модуль
  4. Правило преобразования URL RewriteRule
  5. Директива RewriteCond
  6. Примеры
  7. Битрикс

В сегодняшней статье рассмотрим работу модуля mod_rewrite сервера Apache, и как с помощью правил RewriteRule и RewriteCond работать с URL. Поговорим про описание и логику работы правила RewriteRule, а так же синтаксис некоторых директив модуля mod_rewrite.

Немного теории

Веб-сайты работают благодаря серверам — компьютерам с установленным программным обеспечением, отвечающим за передачу информации от физических хранилищ до браузера пользователя.

Apache — это программное кроссплатформенное обеспечение, основное назначение которого HTTP-сервер.

HTTP сервер или веб-сервер — это программа, которая понимает, что нужно клиенту и выдает ему ответы в виде HTML страниц, на которых может содержаться различная информация: изображения, тексты, скрипты, файлы, медиаданные (видео и аудио) и многое другое.

Apache является самым популярным ПО для веб-серверов в мире, благодаря простоте, гибкости в настройке, надежности, производительности и модульности.

.htaccess — конфигурационный файл Apache, в котором директивами (командами), задаются параметры для работы сервера: разрешение или запрет доступа к директориям, переназначение типов файлов, оптимизация скорости загрузки (можно задать кэш для файлов). Файл .htaccess располагается в корневой директории сервера и распространяется на весь сервер, кроме директорий, где находится другой файл.

Чтобы сервер мог работать с директивами, активируйте модуль mod_rewrite в конфигурационном файле (*.conf). Настройка этого модуля, происходит в файле .htaccess. Как это сделать будет описано ниже.
Команда подключения модулей (LoadModule) прописывается в конфигурационном файле Apache. В зависимости от системы может располагаться:

  1. Linux, CentOS, Fedora (Redhat-системы) — /etc/httpd/conf/httpd.conf;
  2. Apache 2.2 — /etc/apache2/apache2.conf;
  3. Gentoo, Apache 2.0 — /etc/apache2/httpd.conf.

Включить и отключить модуль Apache можно с помощью следующих команд:
a2enmod
a2dismod

Например, подключение модуля rewrite_module происходит с помощью консольной команды:
sudo a2enmod rewrite - включить модуль
sudo systemctl restart apache2 - перезагрузить Apache что бы применилась активация

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

LoadModule rewrite_module modules/mod_rewrite.so

Для этого уберите перед строкой знак “#”.
Также используйте знак решетки если не работает что-то из директив. Поставьте ее перед строкой с кодом. Это позволит закомментировать не нужный Вам текст программа при чтении пропустит данную строку.

Можно добавить рисунок, где видна строка указать что нужно убрать #

Что такое mod_rewrite

Это модуль сервера Apache (программа, работающая на стороне сервера), выполняющий действия с URL, такие как: создание редиректов, ЧПУ, ограничения доступа к директориям на веб-сайте. Главная задача — преобразования URL-ов. Например, рассмотрим перенаправление всех страниц домена oldsite.com на соответствующие страницы newsite.com.
RewriteCond %{HTTP_HOST} ^oldsite\.com
RewriteRule ^(.*)$ http: //newsite .com/$1 [R=301,L]

Как работает модуль

В своей работе mod_rewrite использует регулярные выражения. В них используются специальные символы (метасимволы) и обычные символы (литералы). Основными метасимволами являются: [ ] \ / ^ $ . | ? * + ( ) { }, где наиболее часто используемые спецсимволы:
^ — начало строки;
$ — конец строки;
. — любой символ;
* — любое количество любых символов;
? — один определенный символ;
[0-9] — последовательность символов, например, от 0 до 9;
| — символ «или», выбирается или одна группа, или другая;
() — используется для выбора групп символов.

Порядок обработки правил (команд) прописывается в .htaccess, и составляются примерно в таком порядке:
(проверяем что модуль включен)
RewriteEngine on (один раз сверху)
RewriteCond %{что сравнивать} с чем сравнивать [флаги]
RewriteRule исходный url целевой url [флаги]

Если указано условие RewriteEngine off, то блок IfModule с кодом - будет проигнорирован и не выполнится.

Где:

  1. RewriteEngine включает или отключает преобразование http-ссылок;
  2. RewriteCond - условие, которое должно быть соблюдено перед выполнением правила, условий может быть несколько;
  3. RewriteRule - собственно само правило, которое выполняется при соблюдении условия.

Порядок размещения правил в .htaccess важен, потому что механизм преобразований обрабатывает их в специальном порядке. Условия (RewriteCond) всегда должны быть перед правилами (RewriteRule)!

Правило преобразования URL RewriteRule

Синтаксис директивы RewriteRule:
RewriteRule Шаблон Подстановка [Флаги]

Например:
RewriteRule ^(.*)$ index.php?/$1 [L,QSA]

Где:

  1. RewriteRule это директива;
  2. Шаблон — это символы ^(.*)$. Регулярное выражение применяемое к текущему URL. Читается так. Искать в строке URL от начала строки(^) до конца( $) любой символ (знак .) в количестве от нуля до бесконечности (знак *).
    Например:
    ^stena - Любые строки, начинающиеся со слова stena. Строка, начинающаяся со слова dom-stena не удовлетворит критерию;
    stena$ - Любые строки, заканчивающиеся набором символов stena. Строка, заканчивающаяся на stena-dom под выбор не попадёт;
    [0-9]{1,6}$ - Выбрать все строки, оканчивающиеся от 1 до 6 цифрами из диапазона от 0 до 9.
    В регулярных выражениях есть скобки(). Поэтому часть URL соответствующая условию в скобках добавляется в переменную подстановки $1, которая используется в Подстановке или в Сравниваемая Строка (это в директиве RewriteCond, о ней ниже);
  3. Подстановка — index.php?/$1. Правило преобразования URL. Запись означает, что строка нового, измененного URL должна быть составлена из двух частей, где первая часть строки постоянное значение index.php?/, а вторая часть — значение из переменной подстановки $1. В $1 храниться та часть URL которая соответствовала части регулярного выражения в скобках из параметра Шаблон. Мы получаем преобразованный URL вида index.php?/URL по которому обратились;
  4. [L,QSA] – флаги. Правило означающее, что необходимо остановить процесс преобразования на этом месте и не применять больше никаких следующих правил преобразований для URL. Дополняют преобразование URL Третий аргумент директивы RewriteRule.

Рассмотрим флаги RewriteRule подробнее:

  • [NC]. Делает шаблон нечувствительным к регистру, когда он применяется к текущему URL;
  • [QSA]. Добавляет строку запроса из исходного URL к строке запроса, созданной правилами перезаписи;
  • [L]. Останавливает процесс преобразования на этом месте и не применяет больше никаких правил преобразований;
  • [N]. Перезапускает процесс преобразований (начав с первого правила). В этом случае URL снова сопоставляется неким условиям, но не оригинальный URL, а URL вышедший из последнего правила преобразования;
  • [F]. Веб-сервер возвращает браузеру ошибку с кодом 403;
  • [R]. Редирект с кодом ответа браузеру 302 (временно перемещен);
  • [R=code]. Редирект с кодом ответа браузеру code;
  • [B] (escape backreferences) - заставляет экранировать (кодировать) спец-символы, например взять правило "RewriteRule ^search/(.*)$ /search.php?term=$1" в котором есть строка поиска, которая может содержать к примеру 'x & y/z' и в результате будет возвращена строка 'search.php?term=x & y/z', что неявляется допустимым УРЛ и будет преобразовано браузером в "search.php?term=x%20&y%2Fz=". С флагом [B] строка будет преобразована в "/search.php?term=x%20%26%20y%2Fz". Для работы этого примера понадобится установить AllowEncodedSlashes в On ибо httpd по-умолчанию не позволяет кодировать слэши в УРЛ;
  • [C] chain - объединить несколько правил в цепочку. Если первое правило цепочки не удовлетворяет условиям, тогда вся цепочка будет проигнорирована;
  • [CO] cookie - устанавливает cookie в формате [CO=NAME:VALUE:DOMAIN:lifetime:path:secure:httponly], параметры для secure и httponly устанавливаются как true|false;
  • [DPI] discardpathinfo - отбрасывает PATH_INFO в преобразованной ссылке, полезно использовать в случаях, когда PATH_INFO уже был добавлен в предыдущем преобразовании;
  • [E] env - установить переменную [E=VAR:VAL] или удалить её [E=!VAR];
  • [F] forbidden - возвращает ошибку 403;
  • [G] gone - возвращает ошибку 410;
  • [H] handler - принудительно устанавливает обработчик для определённых типов файлов, например правило "RewriteRule !\. - [H=application/x-httpd-php]" заставит пропустить через PHP все файлы без расширения;
  • [L] last - указывает, что правило является последним и процесс дальнейшего преобразования прекращается;
  • [N] next - начинает процесс преобразования с первого по порядку правила, используйте этот флаг с осторожностью ибо он может привести к замкнутому циклу (т.н. петля);
  • [NC] nocase - отключает проверку регистра символов;
  • [NE] noescape - mod_rewrite обычно применяет правила экранирования URI к результату преобразования. Спецсимволы (такие как '%', '$', ';', и так далее) будут экранированы их шестнадцатеричными (hexcode) подстановками ('%25', '%24', и '%3B', соответственно). Этот флаг запрещает делать это;
  • [NS] nosubreq - игнорировать подзапросы, выполнять правило только для настоящих/прямых запросов;
  • [P] proxy - Apache выполняет подзапрос к указанной странице с использованием программного модуля mod_proxy, при этом клиент об этом подзапросе ничего не узнает. Произойдет ошибка если модуль mod_proxy не подключен;
  • [PT] passthrough - остановить преобразование и передать полученную новую ссылку дальше;
  • [QSA] qsappend - добавляет исходные параметры запроса (query string) к замене. Если в подстановку не включаются новые параметры запроса, то исходные параметры запроса будут добавлены автоматически. Если же новые параметры включаются в подстановку, то исходные параметры запроса будут утеряны если не указать флаг QSA;
  • [R] redirect - возвращает браузеру команду на перенаправление (по-умолчанию код 302 - MOVED TEMPORARY), код редиректа можно указать самостоятельно, например R=301 (код 301 - MOVED PERMANENTLY), но в границах 300-399, в противном случае правило не будет обработано;
  • [S] skip - пропускает следующее правило, если данное правило сработало. Можно указать количество правил, например: S=2;
  • [T] type - принудительно устанавливает MIME-тип целевого файла. К примеру, "RewriteRule \.pl$ - [T=text/plain]", это правило отобразит Perl скрипты в текстовом формате, а значит код скрипта будет выдан в браузер.

rewriterule примеры

Создание понятных для человека URL
ЧПУ — расшифровывается как Человекопонятный URL. Это ссылки которые визуально имеют упрощенную структуру. Ее проще запомнить.
Например, Ссылки вида http://site.com/?page=contacts нужно привести к http://site.com/contacts/.

Все в файле .htaccess пропишите:
RewriteRule ^contacts/?$ ?page=contacts [L,QSA]
RewriteRule ^news/?$ ?page=news [L,QSA]
RewriteRule ^news/([^/]+)/?$ ?page=news&slug=$1 [L,QSA]

Преобразования происходит благодаря флагу QSA (query string append), прописанному в квадратных скобках после каждого правила. Если строка запроса удовлетворяет правилу, она является эквивалентом указанного адреса, и выдает тот же самый контент.
Например, RewriteRule ^news/?$ ?page=news [L,QSA] и обратиться к сайту по адресу /news/, то:

  1. Строка запроса /news/ совпадет с указанным в правиле, значит это правило сработает;
  2. Флаг L (last) указывает, что после этого правила другие применяться не будут;
  3. Флаг QSA указывает на подстановку строки запроса и ее НЕ ЧПУ аналог;
  4. Строка запроса /news/ аналогична НЕ ЧПУ адресу ?page=news;
  5. По запросу /news/ выводится контент точно такой же, как и если набрать ?page=news.

Директива RewriteCond

Синтаксис директивы RewriteCond:
RewriteCond СравниваемаяСтрока Условие [Флаги]

Где:

  1. СравниваемаяСтрока — строка, которая проверяется на соответствие выражению, прописанному в параметре Условие;
  2. Условие — это логическое выражение, по которому проверяется параметр СравниваемаяСтрока. Часто в нем применяют регулярные выражения;
  3. [Флаги]. Задают дополнительные опции, например, можно установить логику объединения правил RewriteCond через логическое И [AND] (по умолчанию) или через логическое ИЛИ [OR]. Или, будет ли сравнение в условии RewriteCond выполнятся с учетом регистра или без учета регистра.

Пример директив RewriteCond, объединенных через логическое И [AND] (по умолчанию):
# одна точка входа, все запросы (кроме файлов и директорий) на /index.php
RewriteCond $1 !=favicon.ico
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php

СравниваемаяСтрока:

  1. может, содержать часть или весь URL.
  2. содержит часть URL можно при помощи переменных подстановки ($1, $2, $3), которые были созданы в соответствующем RewriteRule.
  3. содержит различные переменные из окружения сервера Apache: %{REQUEST_URI}, %{HTTP_HOST}, %{QUERY_STRING}.

Условие может содержать специальные символы:

  • -d — проверка, что директория существует;
  • -f — проверка, что файл существует.

Дополнительно, перед условием, допускается использование логических символов:

  • !Условие — инвертирование значения, т.е. сравниваемая строка должна не соответствовать шаблону условия;
  • =Условие — Условие считается простой строкой и лексически сравнивается с СравниваемаяСтрока. Истинно, если эти две строки полностью одинаковы (символ в символ). Если Условие имеет вид "" — это сравнивает СравниваемаяСтрока с пустой строкой.

Некоторые флаги RewriteCond:

  • [NC] (от No Case). Регистр не имеет значения, как в СравниваемаяСтрока так и в Условие. Этот флаг эффективен только для сравнений между СравниваемаяСтрока и Условие, он не работает при проверках в файловой системе.
  • [OR]. Логическое ИЛИ. Используется, когда перед директивой RewriteRule находится несколько директив RewriteCond и правило в RewriteRule должно быть выполнено при совпадении любого RewriteCond;​
  • [AND]. Логическое И. Используется, когда перед директивой RewriteRule находится несколько директив RewriteCond и правило в RewriteRule должно быть выполнено при совпадении всех RewriteCond. Этот флаг используется по умолчанию, так что его можно опускать.

Пример 1. Правила с набором условий:
RewriteCond $1 !^(index\.php|images|robots\.txt|public) [NC]
RewriteCond %{REQUEST_URI} !\.(css|js|jpg|gif|png)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L,QSA]

Блок директив содержит правило преобразования url и дополнительные условия. Смысл блока в следующем. Для любого url запустить правило перезаписи url. Проверить что url:

  1. Не начинается как index.php или images или robots.txt или public – т.е. не начинается на открытые нами к прямому обращению файлы и каталоги.
  2. Не заканчивается на .css или .js или. Не является файлом к которым мы позволяем обращаться напрямую;
  3. Не является реальным файлом на диске и директорией.

Если условия выполняются собрать новую строку url из двух строк. Где первая строка «index.php?/» вторая — первоначальный url.
Флаг L – закончить на этом правиле все преобразования. Флаг QSA — добавить значение из $1 к результирующей строке URL, а не заменить ее.

Разберем первое дополнительное условие из примера:
RewriteCond $1 !^(index\.php|images|robots\.txt|public) [NC]

Где:

  1. В параметре СравниваемаяСтрока прописывается выражение $1 – это переменная подстановки, в которой находится значение из круглых скобок, взятых из параметра Шаблон директивы RewriteRule. В параметре Шаблон содержится: ^(.*)$. Это означает, что в параметр СравниваемаяСтрока подставиться весь URL;
  2. Параметр Условие содержит оператор инверсии (!)условия и регулярное выражение, возвращающее результат применения его к параметру СравниваемаяСтрока. В данном случае параметр Условие звучит как: не начинается с символов: index.php или images или robots.txt или public;
  3. Флаг [NC]. Сравнивает регистр. Это дополнительное условие понимаем как: если без учета регистра URL не начинается с символов index.php, images, robots.txt, public то условие истинно.

Примеры

Если изначально в индекс поисковой системы попала версия «с www», в файл .htaccess добавляется редирект на «без www»:
RewriteCond %{HTTP_HOST} ^www.name\.site$ [NC]
RewriteRule ^(.*)$ http://name.site/$1 [R=301,L]

Если произошла обратная ситуация и необходима переадресация с без «www» на «www», то в файл прописывается:
RewriteCond %{HTTP_HOST} ^v name\.site$ [NC]
RewriteRule ^(.*)$ http://www.name.site/$1 [R=301,L]

В случае перехода на защищенный протокол https для всего сайта, необходимо настроить перенаправление с http на https, для этого в файл .htaccess добавьте:
RewriteCond %{SERVER_PORT} !^443$
RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]

Если данная конструкция не сработает, попробуйте другой вариант:
RewriteCond %{HTTPS} =on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [QSA,L]

Если циклическое перенаправление на страницах осталось, попробуйте такой вариант:
RewriteCond %{HTTPS} off
RewriteCond %{HTTP:X-Forwarded-Proto} !https

RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Если редирект не работает и в этом случае, попробуйте такой вариант:
RewriteEngine On
RewriteCond %{SERVER_PORT} !^443$
RewriteCond %{REQUEST_URI} =/page.php
RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R,L]

Редирект на .html
Пример, редирект с c site.ru/blog на site.ru/blog.html.
RewriteCond %{REQUEST_URI} (.*/[^/.]+)($|\?)
RewriteRule .* %1.html [R=301,L]
RewriteRule ^(.*)/$ /$1.html [R=301,L]

Редирект на страницу без слеша в конце адреса
Пример, редирект с c site.ru/blog/ на site.ru/blog.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ /$1 [R=301,L]

Редирект на страницу со слешем в конце адреса
RewriteCond %{REQUEST_URI} (.*/[^/.]+)($|\?)
RewriteRule .* %1/ [R=301,L]

Редирект на страницу без index.php в адресе
RewriteRule ^index.php/(.*)$ http://mysite.ru/$1 [R=permanent,L]

Редирект на страницу без index.php в конце адреса
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTP/
RewriteRule ^index\.php$ http://site.ru/ [R=301,L]

Битрикс

Для перенаправления на новую страницу достаточно отредактировать файл .htaccess, внеся в него такой редирект:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.sng-it.ru$ [NC]
RewriteRule ^(.*)$ http://sng-it.ru/$1 [R=301,L]

Простой редирект
RewriteRule ^news/happy.* /news.html [R=301,L]
Для простого редиректа условия задавать не обязательно, только правило.

Реврайт без редиректа RewriteRule ^news/happy.* /news.html [L]
Иногда требуется, чтобы был редирект без смены адреса, т.е. реврайт без редиректа. Для этого просто не указываем флаг редирект (R), и получаем желаемый результат, теперь по адресу news/happy получим news.html, а в адресной строке останется news/happy

Редирект на мобильную версию веб-сайта
Допустим, что мобильная версия расположена поддомене m.site.ru. Переход будет происходить с главной страницы основного домена.
RewriteCond %{HTTP_USER_AGENT} (?i:midp|samsung|nokia|j2me|avant|docomo|novarra|palmos|palmsource|opwv|chtml|pda|mmp|blackberry|mib|symbian|wireless|nokia|hand|mobi|phone|cdm|upb|audio|SIE|SEC|samsung|HTC|mot-|mitsu|sagem|sony|alcatel|lg|eric|vx|NEC|philips|mmm|xx|panasonic|sharp|wap|sch|rover|pocket|benq|java|pt|pg|vox|amoi|bird|compal|kg|voda|sany|kdd|dbt|sendo|sgh|gradi|jb|dddi|moto|iphone|android) [NC]
RewriteCond %{HTTP_HOST} site.ru
RewriteRule ^$ http://m.site.com/ [R=302,L]

Рассмотрим подробнее код:

  1. Первая строка. Проверка USER_AGENT. Определяем что он относится к мобильной версии;
  2. Второй строкой проверяем что мы находимся на нужном домене;
  3. Третьей строкой, мы проверяем, что находимся на главной страницы и перенаправляем на поддомен.

Другие статьи

Отправьте заявку и уже завтра мы начнем работы.

Обязательное поле для заполнения

Обязательное поле для заполнения

Обязательное поле для заполнения

Обязательное поле

Обязательное поле для заполнения

Обязательное поле для заполнения

Обязательное поле

Спасибо за обращение!
В ближайшее время мы с вами свяжемся.

Далее

Обязательное поле для заполнения

Обязательное поле для заполнения

Укажите предпочтительные каналы связи:

ТелефонWhatsAppTelegram

Обязательное поле