Примеры использования mod_rewrite для перенаправлений и настройки чпу. Принудительное использование HTTPS за прокси. Запретить конкретный файл

Основы и особенности mod_rewrite, примеры использования mod_rewrite, переменные сервера, флаги (RewriteRule Flags ), перенаправление, запрет доступа по времени суток или агенту пользователя, запрет доступа по рефереру или при его отсутствии.

Мир Вам Братья и Сёстры! По просьбам трудящихся сегодня я здесь типа обучающая программа, которую зовут Олег, и, сегодня мы с Вами попробуем объяснить, самим себе в первую очередь, основные принципы работы чудо-модуля mod_rewrite дабы иметь отчётливое понимание как работают условия и правила, а не просто тупо их копировать/вставлять. Итак, начнём...

Модуль Apache mod_rewrite является очень мощным, но в то же время сложным, инструментом для манипуляции с URL перенаправлениями/преобразованиями/запретами. С помощью этого чудо-модуля можно выполнять практически любые URL преобразования/манипуляции на стороне сервера.

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

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

mod_rewrite использует Perl Compatible Regular Expression (PCRE - Perl совместимые регулярные выражения ). В этой статье, мы не будем подробно описывать использование регулярных выражений имхо этой теме посвящены целые тома книг и в одной статье нельзя охватить данную тематику.

  • Секреты регулярных выражений (regular expressions): Часть 1. Диалекты и возможности. Составление регулярных выражений

Главное, что нужно помнить, - это то, что в регулярных выражениях используются специальные символы (метасимволы ) и обычные символы (литералы ). Основными метасимволами являются \ / ^ $ . | ? * + () { } . Метасимволы всегда нужно экранировать обратным слэшем "\", - это относится к пробелу ("\ "), а также тому же обратному слэшу ("\\").

Нужно помнить, что mod_rewrite использует оригинальный PCRE (Perl совместимые регулярные выражения ), но с некоторыми дополнениями:

  • "!Условие " (несоответствие условию)
  • "<Условие " (лексически меньше условия)
  • ">Условие " (лексически больше условия)
  • "=Условие " (лексически равно условию)
  • "-d " (является ли каталогом)
  • "-f " (является ли обычным файлом)
  • "-s " (является ли обычным файлом с ненулевым размером)
  • "-l " (является ли символической ссылкой)
  • "-F " (проверка существования файла через подзапрос)
  • "-U " (проверка существования URL через подзапрос)

Порядок обработки правил mod_rewrite

Порядок обработки правил mod_rewrite является далеко не очевидным. Правила mod_rewrite составляются примерно в таком порядке:

RewriteEngine on RewriteBase / # uncomment this line if web-base dir not root # RewriteBase /you-web-base-dir RewriteCond %{что_сравнивать} с_чем_сравнивать [флаги] RewriteRule исходный_url целевой_url [флаги]

Теперь чуть подробнее:

  • RewriteEngine - должна быть одна;
  • RewriteBase - может пригодится при использовании в правилах относительных ссылок, но если относительные ссылки относятся к корню каталога, то данная директива может не использоваться, теоретически может использоваться многократно перед каждым из правил;
  • RewriteCond - условие, которое должно быть соблюдено перед выполнением правила, условий может быть несколько;
  • RewriteRule - собственно само правило, которое выполняется при соблюдении условия.

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

Как видно, Текущий URL сначала сравнивается с Шаблон правила и при совпадении с шаблоном проверяет условия, если Текущий URL удовлетворяет условиям, то к нему применяется правило и Преобраз. URL идёт дальше на обработку если не указан флаг [L] (last ).

Флаг [L] нужно использовать для каждого правила, разумеется если дальнейшая трансформация URL не требуется.

Переменные mod_rewrite

В условиях (RewriteCond) и в правилах (RewriteRule) можно использовать переменные сервера.

1. HTTP headers (RqH - Request Header):

  • HTTP_USER_AGENT - содержит полную строку заголовка "User-Agent:";
  • HTTP_REFERER - адрес с которого пришел пользователь;
  • HTTP_COOKIE - доступ к списку COOKIE браузера;
  • HTTP_FORWARDED - содержит IP-адрес прокси-сервера или сервера балансировки нагрузки;
  • HTTP_HOST - адрес хоста/сервера, который запросил пользователь, например, example.com;
  • HTTP_PROXY_CONNECTION - содержит лексему соединения (connection-token ) "close" или "Keep-Alive", предназначен для согласования постоянных соединений между клиентом и сервером (аналог заголовка Connection);
  • HTTP_ACCEPT - заголовок согласования содержимого, которое поддерживает браузер/клиент пользователя, например " text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 " ("тип/подтип", через запятую, где тип – это тип содержимого, а подтип – это уточнение типа.). Если заголовок Accept содержит " Accept: */* " (*/*), то это означает, что клиент готов принять содержимое любого типа.

2. connection & request (соединение & запрос):

  • REMOTE_ADDR - IP-адрес клиента;
  • REMOTE_HOST - ДНС-имя IP-адреса клиента;
  • REMOTE_PORT - номер текущего порта клиента;
  • REMOTE_USER - содержит имя авторизированного (средствами сервера) пользователя;
  • REMOTE_IDENT - переменная будет установлена только если подключен модуль mod_ident и IdentityCheck установлено в "on", предназначена для работы с Ident протоколом https://ru.wikipedia.org/wiki/Ident;
  • REQUEST_METHOD - метод, которым был сделан запрос, GET|GET|HEAD и т.д.;
  • SCRIPT_FILENAME - полный путь к запрошенному файлу, например /var/www/public_html/script_name.php;
  • PATH_INFO - Содержит предоставленный пользователем путь, который содержится после имени скрипта, но до строки запроса (?). Например, если скрипт был запрошен по URL http://www.example.com/php/path_info.php/some/stuff?foo=bar, то переменная $_SERVER["PATH_INFO"] будет содержать /some/stuff.
  • QUERY_STRING - строка GET запроса, если запрошен адрес http://example.com/index.php?var=1&var=2, то QUERY_STRING будет содержать var=1&var=2;AUTH_TYPE - тип аутентификации, если выполнена HTTP-аутентификация, может быть Basic или Digest.

3. server internals (внутренние сервера):

  • DOCUMENT_ROOT - полный путь к домашнему каталогу пользователя, например /var/www/public_html/
  • SERVER_ADMIN - данные администратора сервера/виртуального_хоста, обычно адрес электронной почты;
  • SERVER_NAME - имя сервера, обычно из директивы ServerName;
  • SERVER_ADDR - IP-адрес сервера;
  • SERVER_PORT - порт сервера;
  • SERVER_PROTOCOL - версия используемого протокола, например HTTP/1.0 или HTTP/1.1;
  • SERVER_SOFTWARE - название/версия сервера.

4. date and time (системные, дата и время):

  • TIME_YEAR - год, 2014
  • TIME_MON - месяц, 05
  • TIME_DAY - день, 07
  • TIME_HOUR - час, 04 (24)
  • TIME_MIN - минуты, 38
  • TIME_SEC - секунды, 55
  • TIME_WDAY - день недели, 3 (среда)
  • TIME - в формате год-мес-день-час-мин-сек, например 20140514234534

5. specials (специальные):

  • API_VERSION - в формате "20051115:33"
  • THE_REQUEST - подробности GET/POST запроса, например "GET /index.html HTTP/1.1"
  • REQUEST_URI - относительный УРЛ запроса "/index.html"
  • REQUEST_FILENAME - полный локальный путь к файлу или скрипту в файловой системе, соответствующего запроса
  • IS_SUBREQ - если выполняется подзапрос, то переменная содержит true, в противном случае false
  • HTTPS - on/off, если используется/неиспользуется HTTPS

6. переменные результата выполнения:

  • $1 - $1, $2 и т.д. образуются при совпадении (шаблона1.*) (шаблона2.*) из RewriteRule
  • %1 - %1, %2 и т.д. образуются при совпадении (шаблона1.*) (шаблона2.*) из RewriteCond
  • Подробнее о HTTP заголовках можно почитать в спецификации rfc2616 Hypertext Transfer Protocol -- HTTP/1.1

Флаги mod_rewrite

Для управления поведением условий (RewriteCond ) и правил (RewriteRule ) в mod_rewrite используются флаги [флаги] .

  • [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 - объединить несколько правил в цепочку. Если первое правило цепочки не удовлетворяет условиям, тогда вся цепочка будет проигнорирована
  • cookie - устанавливает cookie в формате , параметры для secure и httponly устанавливаются как true|false
  • discardpathinfo - отбрасывает PATH_INFO в преобразованной ссылке, полезно использовать в случаях, когда PATH_INFO уже был добавлен в предыдущем преобразовании
  • [E] env - установить переменную или удалить её
  • [F] forbidden - возвращает ошибку 403
  • [G] gone - возвращает ошибку 410
  • [H] handler - принудительно устанавливает обработчик для определённых типов файлов, например правило " RewriteRule !\. - " заставит пропустить через PHP все файлы без расширения
  • [L] last - указывает, что правило является последним и процесс дальнейшего преобразования прекращается
  • [N] next - начинает процесс преобразования с первого по порядку правила, используйте этот флаг с осторожностью ибо он может привести к замкнутому циклу (т.н. петля)
  • nocase - отключает проверку регистра символов
  • noescape - mod_rewrite обычно применяет правила экранирования URI к результату преобразования. Спецсимволы (такие как "%", "$", ";", и так далее) будут экранированы их шестнадцатеричными (hexcode ) подстановками ("%25", "%24", и "%3B", соответственно). Этот флаг запрещает делать это
  • nosubreq - игнорировать подзапросы, выполнять правило только для настоящих/прямых запросов
  • [P] proxy - Apache выполняет подзапрос к указанной странице с использованием программного модуля mod_proxy, при этом клиент об этом подзапросе ничего не узнает. Произойдет ошибка если модуль mod_proxy не подключен
  • passthrough - остановить преобразование и передать полученную новую ссылку дальше
  • 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$ - ", это правило отобразит Perl скрипты в текстовом формате, а значит код скрипта будет выдан в браузер.

Более подробно о флагах читаем в оригинале:

Протоколы разрешённые в mod_rewrite

mod_rewrite будет определять подстановочный УРЛ как внешний если указаны один из протоколов:

  • ajp:// - Apache JServ Protocol
  • balancer:// - Apache Load Balancer
  • ftp:// - File Transfer Protocol
  • gopher:// - Gopher (protocol)
  • http:// - Hypertext Transfer Protocol
  • https:// - Hypertext Transfer Protocol Secure
  • ldap:// - Lightweight Directory Access Protocol
  • nntp:// - Network News Transfer Protocol
  • ldap: - Lightweight Directory Access Protocol
  • mailto: - The mailto URI scheme
  • news: - News Protocol

.htaccess и порядок размещения правил

В файле.htaccess, теоретически, директивы можно указывать как попало, за исключением директив относящихся к rewrite_module. Тем не менее лучше соблюдать некую последовательность:

  1. CORE директивы;
  2. Конфигурация модулей.

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

Примеры mod_rewrite правил

Запрет доступа с помощью mod_rewrite

RewriteCond %{TIME_HOUR}%{TIME_MIN} >2000 RewriteCond %{TIME_HOUR}%{TIME_MIN} <0700 RewriteRule .* - [ F ] # OR RewriteCond %{TIME_HOUR} >=20 RewriteCond %{TIME_HOUR} <07 RewriteRule .* - [ F ]

Это правило закроет доступ с 8-и вечера и до 7-и утра. Приведённый выше пример специально для любителей копи/пасты содержит преднамеренную ошибку в синтаксисе, HTTP 500 (ошибка сервера ), которая повлечёт запись в логе ошибок RewriteRule: bad flag delimiters . Переводится, как плохой разделитель флагов, - вместо [ F ] нужно использовать [F] , т.е. избегать пробелов и прочих разделителей, кроме запятой!

2. Наглухо запрещаем боту WBSearchBot трогать наш сайт:

RewriteCond %{USER_AGENT} WBSearchBot RewriteRule .* - [F] # Ещё как вариант, вместо ошибки 403 (FORBIDDEN), отдаём ошибку 404 (NOT FOUND) RewriteCond %{USER_AGENT} WBSearchBot RewriteRule .* -

Хотя, немного подправив правило, можно т.с. перевести стрелы на кого-то ещё, так сказать натравить бота на другой сайт, мол...ты что, офонарел!? Иди тренируйся, вон, на нём... :)) (из Х/Ф Операция «Ы» и другие приключения Шурика):

RewriteRule .* http://kremlin.ru

WBSearchBot (Mozilla/5.0 (compatible; WBSearchBot/1.1; +http://www.warebay.com/bot.html) ) довольно агрессивный бот и от него можно смело избавляться.

# BLOCK POST REQUEST FOR OLD HTTP PROTOCOL... RewriteCond %{THE_REQUEST} ^POST RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.|www1\.)?example.com RewriteCond %{THE_REQUEST} POST(.*)HTTP/(0 \.9|1 \.0) RewriteCond %{HTTP_USER_AGENT} ^$ RewriteRule .* -

В предыдущем примере код ответа 303 See Other указан не случайно, - дело в том, что если метод перенаправления (обычно GET ) отличается от метода запроса (например POST ), то в случае возврата кодов ответа 301-302 вместо автоматического редиректа в браузер будет выдана страница со ссылкой для ручного перехода по ней! В случае же с ответом 303 See Other перенаправление выполняется автоматически методом GET независимо от метода запроса.

4. Hotlink protection - запрещаем отображение наших изображений с других сайтов:

# # HOTLINK PROTECT... # http://www.htaccesstools.com/hotlink-protection/ RewriteCond %{HTTP_REFERER} !^$ RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.|www1\.)?сайт RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?google.com RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?yandex.ru RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?subscribe.ru RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?feedburner.com RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?mail.ru RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?poisk.ru RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?rambler.ru RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?nigma.ru RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?ask.com RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?qip.ru RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?ukr.net RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?conduit.com RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?tut.by RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?bing.com RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?webalta.ru RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?yahoo.com RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?conduit.com RewriteRule \.(jpg|jpeg|png|gif) https://dl.dropboxusercontent.com/u/52572427 / \ images/wrs-hotlink-deny .jpg

  • RewriteRule ^ - RewriteCond %{HTTPS} on RewriteRule ^ - # To redirect all users to access the site WITH the "www." prefix, # (http://example.com/... will be redirected to http://www.example.com/...) # uncomment the following: RewriteCond %{HTTP_HOST} . RewriteCond %{HTTP_HOST} !^www\. RewriteRule ^ http%{ENV:protossl}://www.%{HTTP_HOST}%{REQUEST_URI} # OR # REDIRECT FOR /DOCS Redirect permanent /docs http://docs.example.com

    2. Перенаправляем наши RSS/ATOM ленты на FeedBurner

    # REDIRECT blog RSS/ATOM to FeedBurner... RewriteCond %{HTTP_USER_AGENT} !^.*(FeedBurner|FeedValidator) RewriteCond %{QUERY_STRING} ^option=com_content&view=featured&Itemid=()+&format=feed RewriteRule index.php http://feeds.feedburner.com/remote-shaman-blog? # # REDIRECT forum RSS/ATOM to FeedBurner... # if HTTP_USER_AGENT not FeedBurner or FeedValidator RewriteCond %{HTTP_USER_AGENT} !^.*(FeedBurner|FeedValidator) # forum/topics/mode-topics?format=feed # forum/topics/mode-latest?format=feed # forum/topics/posts?format=feed # forum/recent?format=feed RewriteCond %{QUERY_STRING} ^format=feed$ RewriteRule forum/(*/)?()+ http://feeds.feedburner.com/remote-shaman-forum?

    Обратите внимание, что в конце каждой ссылки в правилах (RewriteRule ) стоит символ "?", - он требуется для того, чтобы в конец ссылки, по которой будет перенаправлен запрос, не добавлялись параметры QUERY_STRING! если не указать символ "?", то в итоге перенаправление будет по адресу http://feeds.feedburner.com/remote-shaman-blog?option=com_content&view=featured&Itemid=... и http://feeds.feedburner.com/remote-shaman-forum?format=feed соответственно.

    Итоги

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

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

    При написании данного материала использовались только оригинальные маны с сайта httpd.apache.org (никакой копи/пасты). Если я что-то пропустил аль где-то протупил, тогда обязательно напишите об этом в комментариях.

RewriteRule определяет правила для механизма преобразований

Синтаксис: RewriteRule Шаблон Подстановка (пример, RewriteRule ^tags$ /tags.php [L] )

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

В качестве третьего аргумента директивы RewriteRule. Флаги — это разделённый запятыми, следующий список флагов:

  • "redirect|R [=code]" (вызывает редирект)

Префикс в Подстановке вида http://thishost[:thisport]/ (создающий новый URL из какого-либо URI) запускает внешний редирект (перенаправление). Если нет накакого кода в подстановке ответ будет с HTTP статусом 302 (ВРЕМЕННО ПЕРЕМЕЩЕН). Если вы хотите использовать дркгие коды ответов в диапазоне 300-400, просто напишите их в виде числа или используйте одно из следующих символических имён: temp (по-умолчанию), permanent, seeother. Используйте это в директивах, которые должны преобразовывать некие виртуальные URL в реальные и возвращать их клиенту, например, преобразовывать «/~» в «/u/» или всегда добавлять слэш к /u/user, и т.д.

Примечание: При использовании этого флага, убедитесь, что поле подстановки, это работающий URL! Если это не так, вы перенаправляете в никуда! И помните, что сам по себе этот флаг, только дополняет URL строкой http://thishost[:thisport]/, и процесс преобразования продолжается. Также, обычно вы хотите остановиться и сделать этот редирект немедленно. Для остановки процесса преобразования, вам также нужно написать флаг "L".

  • "forbidden|F" (делает URL запрещенным)

Это делает текущий URL запрещённым, например, клиенту немедленно отправляется ответ с HTTP статусом 403 (ЗАПРЕЩЕНО). Используйте этот флаг в сочетании с соответствующими RewriteConds для блокирования URL по некоторым критериям.

  • "gone|G" (делает URL «мёртвым»)

Этот флаг делает текущий URL «мертвым», т.е., немедленно отправляется HTTP ответ со статусом 410 (GONE). Используйте этот флаг для маркировки «мертвыми» не существующие более страницы.

  • "proxy|P" (вызвает прокси)

Этот флаг помечает подстановочную часть как внутренний запрос прокси и немедленно (т.е., процесс преобразования здесь останавливается) пропускает его через прокси модуль. Вы должны убедиться, что строка подстановки это реальный URI (например, типично начинающийся с http://hostname), который может быть обработан прокси модулем Apache. Если это не так, вы получите ошибку от прокси модуля. Используйте этот флаг для того, чтобы добиться более мощной реализации диркетивы ProxyPass, интегрирующей некоторое содержимое на удаленных серверах, в пространство имён локального сервера.

Примечание: Для того чтобы это использовать убедитесь что у вас есть работающий прокси модуль на вашем сервере Apache. Если вы не знаете этого проверьте есть ли в выводе «httpd -l» строчка mod_proxy.c. Если да, эти возможности доступны mod_rewrite. Если нет, то сначала вы должны пересобрать программу «httpd» с включенным прокси модулем.

  • "last|L" (последнее правило)

Остановить процесс преобразования на этом месте и не применять больше никаких правил преобразований. Это соответствует оператору last в Perl или оператору break в языке C. Используйте этот флаг для того, чтобы не преобразовывать текущий URL другими, следующими за этим, правилами преобразований. К примеру, используйте это для преобразования корневого URL из ("/") в реальный, например, "/e/www/".

  • "next|N" (следуюший раунд)

Перезапустить процесс преобразований (начав с первого правила). В этом случае URL снова сопоставляется неким условиям, но не оригинальный URL, а URL вышедший из последнего правила преобразования. Это соответствует оператору next в Perl или оператору continue из языка C. Используйте этот флаг для перезапуска процесса преобразований, т.е., безусловному переходу на начало цикла.

Однако будьте осторожны, для того чтобы не сделать бесконечный цикл!

  • "chain|C" (связь со следующим правилом)

Этот флаг связывает текущее правило со следующим (которое, в свою очередь, может быть связано со следующим за ним, и т.д.). Это имеет следующий эффект: если есть соответствие правилу, процесс продолжается как обычно, т.е., флаг не производит никакого эффекта. Если правило не соответствует условию, все следующие, связанные правила, пропускаются. Например, импользуйте это для удаления «.www» части в конфигурационном правиле контекста каталога работающего когда вы разрешаете внешний редирект (где не должно быть «.www»!).

  • "type|T=MIME-тип" (принудительно установить MIME тип)

Принудительно установить MIME-тип целевого файла в MIME-тип. К примеру, это можно использовать для имитации mod_alias директивы ScriptAlias которая принудительно устанавливает для всех файлов внутри отображаемого каталога MIME тип равный «application/x-httpd-cgi».

  • "nosubreq|NS" (используется только в случае невнутреннего подзапроса)

Этот флаг дает команду механизму преобразований пропустить директиву если текущий подзапрос является внутренним подзапросом. К примеру, внутренние подзапросы в Apache происходят тогда, когда mod_include пытается получить информацию о возможных файлах по-умолчанию для каталогов (index.xxx). При подзапросах это не всегда полезно и даже иногда вызывает проблему в работе всего набора директив преобразований. Используйте этот флаг для исключения некоторых правил.

Используйте следующее правило по своему усмотрению: всякий раз когда вы предваряете некоторые URL префиксом передавая их на обработку CGI-скрипту, — велик шанс что вы напоретесь на проблемы (или даже на ненужные издержки) в случае применения подзапросов. В этих случаях, используйте этот флаг.

  • "nocase|NC" (не учитывать регистр)

Это делает Шаблон нечуствительным к регистру, т.е., нет различий между "A-Z" и "a-z" когда Шаблон применяется к текущему URL.

  • "qsappend|QSA" (добавлять строку запроса) - Query String Append

Этот флаг указывает механизму преобразований на добавление а не замену, строки запроса из URL к существующей, в строке подстановки. Используйте это когда вы хотите добавлять дополнительные данные в строку запроса с помощью директив преобразований.

Пример на learnsongs.ru:

RewriteRule ^tags/([-A-Za-z0-9_’]+)$ /tags.php?tag=$1

RewriteRule ^tags/([-A-Za-z0-9_’]+)?page=(+)$ /tags.php?tag=$1&page=$2

  • "noescape|NE" (не экранировать URI при выводе)

Этот флаг не даёт mod_rewrite применять обычные правила экранирования URI к результату преобразования. Обычно, специальные символы (такие как "%", "$", ";", и так далее) будут экранированы их шестнадцатиричными подстановками ("%25", "%24", и "%3B", соответственно); этот флаг не дает это делать. Это позволяет символам процента появлятся на выходе, как в

RewriteRule /foo/(.*) /bar?arg=P1\%3d$1

Для которого "/foo/zed" преобразовывалось бы в безопасный запрос "/bar?arg=P1=zed".

  • "passthrough|PT" (пропускать через следующий обработчик)

Этот флаг даёт команду механизму преобразований устанавливать поле uri внутренней структуры request_rec равным полю filename. Этот флаг, просто лишь хитрый трюк, для того чтобы иметь возможность обработки вывода директив RewriteRule, директивами Alias, ScriptAlias, Redirect, и т.д. из других трансляторов URI-имя файла. Тривиальный пример для показа этой семантики: если вы хотите преобразовать /abc в /def с использованием механизма преобразований mod_rewrite и затем /def в /ghi с использованием mod_alias:

RewriteRule ^/abc(.*) /def$1

Alias /def /ghi

Если вы опустите флаг PT, mod_rewrite прекрасно сделаетс свою работу, т.е., он преобразует uri=/abc/... в filename=/def/... как должен делать полностью API-совместимый транслятор URI-имя файла. Затем настаёт очередь mod_alias пытающегося сделать переход URI-имя файла который и не будет работать.

Примечание: Вы должны использовать этот флаг если вы хотите смешивать директивы разных модулей содержащих трансляторы URL-имя файла. Типичный пример это использование модулей mod_alias и mod_rewrite..


Примеры записей в htaccess: Индексный файл , Редирект с сохранением рейтинга страницы, Склеивание www и http , Создание ЧПУ или ЧеловекуПонятныхУрлов, Редирект всех файлов папки на один файл, Защита от хотлинков , Определение кодировки и многое другое!

Указываем индексный файл (который первым открывает при обращении к сайту)

DirectoryIndex index.php index.html index.shtml
Можно указать один или несколько файлов

Редирект htaccess php

Redirect / http://www.newsite.ru/
Глобальный редирект(первый /) ВСЁ пересылаем на новый адрес http://www.newsite.ru/

Redirect /katalog http://www.newsite.ru/newkatalog
Все обращения к katalog переадресуем на домен newsite.ru в раздел newkatalog

Редирект с сохранением рейтинга страницы

Redirect 301 /old/old.php http://www.yoursite.ru/new.php
old - пример пути старой страницы. new - пример пути новой страницы.

Редирект пользователя с конкретным ip

SetEnvIf REMOTE_ADDR 192.100.220.1 REDIR="redir"
RewriteCond %{REDIR} redir
RewriteRule ^/$ /out.html
Конкретного пользователя (надоел он или нужно его переслать на внутренний раздел) с данным ip пересылает на страницу /out.html

Склеивание www и http htaccess php

Уже многим SEO (продвижение и оптимизация) известно, что для Поисковых Систем адреса с/без www - это разные адреса и доступность сайта с www отрицательно влияет на индексацию и ранжирование. Поэтому зачастую SEO просят разработчиков склеить сайт без www (чтобы при обращении к сайту с www происходила пересылка на без www, т.е. только http)

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.yoursite\.ru$
RewriteRule ^(.*)$ http://yoursite.ru/$1
Теперь даже если Вы наберёте в адресной строке www.yoursite.ru , то сервер перешлёт Вас на http://yoursite.ru

Создание ЧПУ или Человеко-Понятных-Урлов htaccess php

RewriteEngine on
RewriteRule ^article/([^/\.]+)/?$ article.php?id=$1 [L]
После добавления данной строки в .htaccess будут доступны два адреса для документа. Например: и www.yoursite.ru/article/1

RewriteEngine on
RewriteRule cat/(.*)/(.*)/$ /art.php?$1=$2
В результате www.yoursite.ru/art.php?type=123 превращается в www.yoursite.ru/cat/type/123/ :

Вот ещё частные варианты:

RewriteEngine on
RewriteRule katalog-saitov[/]*$ article.php?id=$1 [L]
Статья с технически адресом www.yoursite.ru/article.php?id=1 теперь будет доступна со своим понятным человеку названием www.yoursite.ru/katalog-saitov .

Редирект всех файлов папки на один файл

Например вы больше не нуждаетесь в разделе сайта articles и хотите перенаправить все запросы к папке /articles на один файл /non-articles.php. Поможет код ниже

RewriteRule ^articles(.*)$ /non-articles.php

Защита от хотлинков htaccess php

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

RewriteEngine On
#В строке с?yoursite\.ru/ меняете данную конструкцию на УРЛ Вашего сайта
RewriteCond %{HTTP_REFERER} !^http://(.+\.)?yoursite\.ru/
RewriteCond %{HTTP_REFERER} !^$
#Меняем /images/exit.jpg на другое изображение. Можно неприличное
RewriteRule .*\.(jpe?g|gif|bmp|png)$ /images/exit.jpg [L]

Определение кодировки htaccess php

Дополнительные варианты самых популярных кодировок: UTF-8, Windows-1251, KOI8-R . В примерах рассмотрим самую распространённую UTF-8
AddDefaultCharset UTF8 # кодировка файлов, в которой по умолчанию отдаёт документы
AddCharset UTF8 .html # Пример: обрабатывает в данной кодировке html
AddCharset UTF8 * # Пример: обрабатывает в данной кодировке Все файлы

# Обработка в данной кодировке определённого файла

AddCharset UTF8 .html

CharsetDisable On # Отменяем перекодировку Сервером загруженных файлов
CharsetDefault UTF8 # Кодировка, передаваемая Сервером Браузеру по умолчанию
CharsetSourceEnc UTF8 # Принудительная Перекодировка ВСЕХ загруженных на сервер файлов

Создание своих страниц ошибок

Если Вам хочется видеть после неправильной ссылки другую страницу, сделанную, например, самим собой, то указываем в.htaccess следующий код (ну и соответственно делаем там свои страницы):

# ошибка сервера, неверный запрос
ErrorDocument 400 /error/badrequest.html

# вход запрещён
ErrorDocument 403 /error/forbid.html

# самая распространённая - страница не найдена
ErrorDocument 404 /error/notfound.html

# внутренняя ошибка сервера
ErrorDocument 500 /error/serverr.html

Запрещаем доступ

Скорее всего Вы столкнётесь с тем, что часть файлов и директорий надо будет закрыть от общего доступа.

Закрываем от всех

Deny from all

Закрываем конкретный файл от всех


deny from all

Разрешаем доступ только с одного ip

Order deny,allow
deny from all
allow from 192.111.37.125

Запрещаем доступ с конкретных ip


order allow,deny
allow from all
deny from 192.111.35.122
deny from 192.111.37.171

Убираем из Урла (URL) расширение файла

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.php
# php можно заменить другим расширением. Например: html, htm, shtml, asp

Запрещаем отображать содержимое директории, если нет индексного файла

Вы скорее всего хоть раз видели текст Index of и список файлов. Так происходит в том случае, когда в директории нет индексного файла (например index.php), а система предлагает выбрать файл для дальнейшего открытия. Минус этого заключается в том, что случайный пользователь может увидеть список и содержание всех файлов директории.
Options -Indexes

Для перенаправления, настройки чпу на веб сайтах использующих и , и вставки ключевых слов в url`ы статей, все директивы прописанные в данной статье прописываются в файле .htaccess который обычно находится в корне вашего сайта, хотя в некоторых cms он есть практически в каждой в папке но это уже совсем другая история….

Ниже приведены 5 примеров использования данного модуля:

1) Переделываем «product.php?id=12» в «product-12.html»

Это простое перенаправление, в котором расширение.php спрятано из адресной строки браузера и динамический УРЛ (с знаком вопроса «?») преобразован в статический адрес

RewriteEngine on
RewriteRule ^product-(+)\.html$ product.php?id=$1

2) Переделываем «product.php?id=12» в «product/ipod-nano/12.html»

Эксперты SEO всегда предлагают показывать главное ключевое слово в УРЛе. В пример Вы можете видеть название продукта в УРЛе.

RewriteEngine on
RewriteRule ^product/(+)/(+)\.html$ product.php?id=$2

3) Перенаправление адресов без www URL на адреса с www — редирект

Если Вы введете yahoo.com в браузере, Вас перенаправит на www.yahoo.com. Для проделывания такой же операции на Вашем сайте добавьте следующий код в файл.htaccess:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^optimaxwebsolutions\.com$
RewriteRule (.*) http://www.optimaxwebsolutions.com/$1

УРЛ сайта, конечно же, поменяйте на свой. Для чего делать такой редирект? Чтобы избежать дублирования сайта поисковиками с www и без www.

4) Переделываем «yoursite.com/user.php?username=xyz» в «yoursite.com/xyz»

В файл.htaccess добавляем следующие строки:

RewriteEngine On
RewriteRule ^(+)$ user.php?username=$1
RewriteRule ^(+)/$ user.php?username=$1

5) Перенаправление домена на новый поддомен или папку.

Допустим, Вы сделали редизайн на сайте и обновленный сайт находится в папке “new” в корне сайта. То есть новый сайт доступен по адресу “test.com/new”. Перенос файлов из одного места в другое может быть довольно трудоемким процесом, так что просто добавьте следующие строки в файл.htaccess и разместите его в корневой папке:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^test\.com$ RewriteCond %{HTTP_HOST} ^www\.test\.com$
RewriteCond %{REQUEST_URI} !^/new/
RewriteRule (.*) /new/$1

Теперь при обращение к «www.test.com» все файлы будут браться из “test.com/new”

mod_rewrite: статический ЧПУ-адрес с одной переменной

Итак, в этой статье я говорил, что сайты на PHP и MySQL имеют адреса следующего формата:

Как правило, такие адреса называют динамическими. Вот мы сейчас и займёмся преобразованием динамических адресов в ЧПУ.

Допустим, нужно преобразовать из lis.php?id=3 в bols3.hi . Регулярное выражение будет иметь следующий формат:

RewriteRule ^НАЗВАНИЕ СТРАНИЦЫ(+)\.РАСШИРЕНИЕ$ ИМЯ НАСТОЯЩЕГО АДРЕСА.php?ПЕРЕМЕННАЯ=$НУМЕРАЦИЯ

То есть в нашем случае получаем следующее:

RewriteRule ^bols(+)\.hi$ lis.php?id=$1

Теперь вместо адреса lis.php?id=90 (где 90 — id) мы можем спокойно обращаться к bols90.hi .

mod_rewrite: статический ЧПУ-адрес с множеством переменных

Рассмотрим такую ситуацию, когда нужно преобразовать адрес с множеством переменных. Например, из lis.php?id=345&cat=3 в bols345-3.hi . Ситуация похожая, но сейчас используется две GET-переменные. В качестве разделителя используется тире. Получаем следующее выражение:

RewriteRule ^bols(+)-(+)\.hi$ lis.php?id=$1&cat=$2

Графически сам принцип преобразования будет выглядить следующим образом:

mod_rewrite: архивный ЧПУ-адрес

Многие архивы на сайте имеют адрес archive.php?year=2003&month=10 . Мы же преобразуем его в archive/2003/10/ . Получаем следующую строку:

RewriteRule ^archive/(+)/(+)\$ archive.php?year=$1&month=$2

mod_rewrite: ЧПУ-адрес для тегов

Сейчас теги присутствуют почти на каждом блоге и сайте. Попробуем изменить адрес для тега winter — posts.php?tag=winter в posts/tags/winter/ . Имеем следующее выражение:

RewriteRule ^posts/tags/(+)\$ posts.php?tag=$1

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

andew

2015-02-13T11:59:58+00:00

2018-03-02T04:50:41+00:00

34141

В статье я привожу описание логики работы правилаRewriteRule и синтаксис некоторых директив модуля mod_rewrite сервера Apache. Также я выделил и обобщил несколько выводов-постулатов, которые, как мне кажется, нужно обязательно знать и понимать при использовании этого модуля. Надеюсь, что все это позволит вам, так же, как и мне ранее, разобраться с работой этого модуля, предоставляющего мощный функционал для выполнения различных преобразований над URL .

Не забывайте в регулярном выражении экранировать служебные символы. Иногда забывают экранировать точку, когда она должна выступать именно как точка, а не как принято в регулярном выражении - как любой символ.

Также не забывайте оборачивать весь блок правил для mod_rewrite в тег:

Не пишите излишне много директив для mod_rewrite , пишите только те правила преобразования, которые вам действительно необходимы. Особенно нужно быть аккуратным с внешними ридиректами - это такие ридиректы, которые выполняются путем отправки клиенту серверного заголовка с кодом НЕ 200 (отдача полноценной страницы), а с другим кодом (чаше всего 301 и 302 ) и которые приводят к перенаправлению в браузере клиента на другой URL т.е. к совершению нового запроса на клиенте. Поэтому любой внешний ридирект всегда приводит к потере времени в обработки запроса, т.к. нужно отправить клиенту ответ, он должен его прочитать, и повторить запрос уже по новому URL. Это затратная по времени процедура. Поэтому ридиректы должны быть только если они действительно вам необходимы.

Учитывайте, что браузеры могут кешировать редиректы, при этом Ctrl+F5 или Ctrl+R не снимает проблему. Поэтому отключайте кеширование в браузере при тестировании ваших правил rewrite модуля web сервера Apache .

Для поиска ошибок работы ваших правил читайте логи Apache .

Не делайте тупой копи-паст директив из различных статей в интернете в свои файлы настроек apache. Cтатьи пишут люди и поэтому возможны ошибочные написания директив, и если учесть, что метод написания статей также подразумевает активное использование копипаста, то ошибки могут распространяться и множиться. Используйте статьи только как справку, а в свои настроечные файлы вписываете директивы из руководств. Хотя это тоже не гарантирует на сто процентов от ошибок, но хотя бы вы из минимизируете.

В этой статье я описал только две директивы и главные на мой взгляд понятия. Однако, как сами понимаете, mod_rewrite предоставляет много других директив и функционала.



Понравилась статья? Поделиться с друзьями: