Содержание

.htaccess

15.10.2014

Почему то на просторах рунета информация о локальной настройки веб-сервера Apache посредством конфигурационного файла .htaccess приводится как то не полно и однобоко. В основном приводятся примеры (часто не рабочие) или сухой перевод англоязычной документации.

А как же быть, если нужно настроить несколько редиректов, и совсем нет времени познавать всю мощь .htaccess? Единственный выход это брать готовые примеры, и наугад адаптировать под свои нужды. В этой статье я напишу краткое руководство по .htaccess, которое закроет большинство вопросов новичков. А также приведу ссылки на подробные инструкции. Эта статья будет дописываться по мере необходимости, начну с самого основного.

Редиректы

Редиректы осуществляются с помощью модуля mod_rewrite. Задаются правила преобразований в виде следующей конструкции:


<IfModule mod_rewrite.c>
  Options +FollowSymLinks
  RewriteEngine On

  [СЮДА ПИШЕМ ПРАВИЛА]  

</IfModule>

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


RewriteCond [СТРОКА ДЛЯ СРАВНЕНИЯ] [УСЛОВИЕ] [ФЛАГИ]
RewriteCond [СТРОКА ДЛЯ СРАВНЕНИЯ] [УСЛОВИЕ] [ФЛАГИ]
RewriteRule [ШАБЛОН] [СТРОКА ПОДСТАНОВКИ] [ФЛАГИ]

Строки RewriteCond — задают условия для срабатывания следующего за ними правила RewriteRule. Условий может быть несколько, они накладываются по правилу AND. Но можно изменить правило на OR с помощью флага OR.

В качестве [СТРОКИ ДЛЯ СРАВНЕНИЯ] могут использоваться различные переменные. Ссылка на полный список Я приведу только те, которые нужны чаще всего:

%{REQUEST_URI} Строка запроса (без доменного имени, и GET параметров), пример «/server/htaccess/»
%{HTTP_HOST} Доменное имя, например «max22.ru»
%{QUERY_STRING}Строка GET параметров

[УСЛОВИЕ] также как и [ШАБЛОН] представляют собой perl совместимое регулярное выражение, с некоторыми дополнениями, позволяющими например проверить файл ли это, или существующий url.

[ФЛАГИ] Флаги пишутся в квадратных скодках через запятую: [NC,OR]. Флаги для условий:

NC Регистронезависимая проверка
OR Условие сопостовляется с остальными про правилу ИЛИ

Подвыражения в регулярных выражениях (заключенные в скобки), доступны для вставки в [СТРОКУ ПОДСТАНОВКИ], обращаться к подвыражениям нужно так: %N — для подвыражений в условиях (RewriteCond) и $N — для подвыражений в правилах (RewriteRule), где N — порядковый номер подвыражения.

RewriteRule — правило подстановки. Если запрос подходит под вышестоящие проверки и [ШАБЛОН]

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

NC Регистронезависимая проверка
R=301 Будет редирект с кодом 301, можно указать другой код
L Это последнее правило, больше не применять правил преобразований

Надеюсь после моего краткого ввода в теорию, вам будет проще понимать что же написано в вашем .htaccess. Привожу ссылку на очень хороший перевод про модуль mod_rewrite, там же можно найти другие хорошие переводы.

Внимание! Браузеры кешируют редиректы!!!

Причем обычные сочетания типа Ctrl+F5 или Ctrl+R не помагают. Я во время тестирования каждый раз открываю страницу в НОВОМ окне в режиме инкогнито. Причем старые страницы в режими инкогнито надо закрывать.

Примеры

Универсальный редирект с www на без www

Тут самое интересное, почему то везде приводятся примеры, жестко привязанные к домену сайта. Зачем?, если есть универсальное решение:


RewriteCond %{HTTP_HOST} ^www\.(.*) [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

Проверяем доменное имя, если оно начинается с www, то сработает правило: «все, на http://%1/$1«. Здесь %1 это наш домен без www (взят из условия), а $1 это адрес (взят из самого правила).

Универсальный редирект с без www на www


RewriteCond %{HTTP_HOST} ^(.*)$ [NC]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%1/$1 [R=301,L]

Тут маленько сложнее. Первое условие нужно для того чтобы получить домен (%1), оно всегда истина. Второе условие проверяет, что домен начинается не с www. Ну и само правило, аналогичное предыдущему примеру

Простой редирект


RewriteRule ^news/happy.* /news.html [R=301,L]

Для простого редиректа условия задавать не обязательно, только правило.

Реврайт без редиректа


RewriteRule ^news/happy.* /news.html [L]

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

Редирект от GET параметров

Например, нужно что бы со страницы /?action=page&id=15 был редирект на /page/15/:


RewriteCond %{QUERY_STRING} action=page [NC]
RewriteCond %{QUERY_STRING} id=(\d+) [NC]
RewriteRule .* /page/%1/? [R=301,L]

Поясню, первым условиям проверяем что есть get параметр action=page, вторым условием проверяем что id равно числу. Эти условия нельзя объединять, т.к. параметры могут идти и наоборот, т.е. index.php?action=page&id=15 и index.php?id=15&action=page должны быть равноценны. Но и наконец правило, там все обычно, кроме знака вопрос (?) на конце. Он нам нужен, чтобы отсечь исходные GET параметры, иначе получим /page/15/?action=page&id=15

Редирект на мобильную версию сайта

Допустим, что мобильная версия расположена на поддомене 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]

Первой строкой мы проверяем USER_AGENT, определяем что он относится к мобильникам. (эту строку я детально не проверял, взял на просторе интернета, возможно она не совсем корректная, или есть более универсальная строка. Но на моих мобильных устройствах этот пример работает)

Второй строкой проверяем что мы находимся на нужном домене (т.к. пример не универсальный)

Третьей строкой, мы проверяем, что находимся на главной страницы (без всяких параметров и прочего) и перенаправляем на поддомен.

Универсальная версия

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


RewriteCond %{HTTP_HOST} ^(.*)$ [NC]
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]
RewriteRule ^$  http://m.%1 [R=302,L]

Редирект с главной страницы

Речь идет про запрос типа site.ru (без site.ru/index.php)

Здесь оказалось не все так очевидно, я столкнулся с необъяснимым поведением.

Реврайт без редиректа (урл не меняется). Рабочий вариант:


RewriteRule ^index.php$  /about/ [L]

Редирект. НЕ рабочий вариант:


RewriteRule ^index.php$  /about/ [R=301,L]

Реврайт без редиректа (урл не меняется). НЕ рабочий вариант:


RewriteRule ^$  /about/ [L]

Редирект. Рабочий вариант:


RewriteRule ^$  /about/ [R=301,L]

Если мне кто — нибудь расскажет почему эти примеры работают крест накрест, а обратно не работают — буду очень рад.

Директива RewriteCond файла .htaccess

У Вас в браузере заблокирован JavaScript. Разрешите JavaScript для работы сайта!

Директива RewriteCond

Описание: Определяет условие при котором происходит преобразование
Синтаксис: RewriteCond СравниваемаяСтрокаУсловие
Значение по умолчанию: None
Контекст: server configvirtual hostdirectory.htaccess
Разрешение: FileInfo
Статус: Расширение
Модуль: mod_rewrite

Директива RewriteCond определяет условия для какого-либо правила. Перед директивой RewriteRule располагаются одна или несколько директив RewriteCond. Следующее за ними правило преобразования используется только тогда, когда URI соответствует условиям этой директивы и также условиям этих дополительных директив.

СравниваемаяСтрока строка которая может содержать следующие дополнительные конструкции вдополении к простому тексту:

  • RewriteRule обратные_связи: Это обратные связи вида

    $N

    (0 <= N<= 9) предоставляющие доступ к сгруппированным частям (в круглых скобках!) шаблона из соответствующей директивы RewriteRule (единственной, следующей сразу затекущим набором директив RewriteCond).
  • RewriteCond обратные_связи: Это обратные связи вида

    %N

    (1 <= N<= 9) предоставляющие доступ ксгруппированным частям (в круглых скобках!) шаблона из соответствующей директивы RewriteCond втекущем наборе условий.
  • RewriteMap расширения: Это расширения вида

    ${mapname:key|default}

    Смотрите документацию по RewriteMap для получения более подробной информации.
  • Переменные сервера: Это переменные вида

    %{NAME_OF_VARIABLE}

    где NAME_OF_VARIABLE может быть строкой взятой из следующего списка:
    HTTP заголовки:соединение & запрос:
    HTTP_USER_AGENT
    HTTP_REFERER
    HTTP_COOKIE
    HTTP_FORWARDED
    HTTP_HOST
    HTTP_PROXY_CONNECTION
    HTTP_ACCEPT
    REMOTE_ADDR
    REMOTE_HOST
    REMOTE_USER
    REMOTE_IDENT
    REQUEST_METHOD
    SCRIPT_FILENAME
    PATH_INFO
    QUERY_STRING
    AUTH_TYPE
    внутренние сервера:системные:специальные:
    DOCUMENT_ROOT
    SERVER_ADMIN
    SERVER_NAME
    SERVER_ADDR
    SERVER_PORT
    SERVER_PROTOCOL
    SERVER_SOFTWARE
    TIME_YEAR
    TIME_MON
    TIME_DAY
    TIME_HOUR
    TIME_MIN
    TIME_SEC
    TIME_WDAY
    TIME
    API_VERSION
    THE_REQUEST
    REQUEST_URI
    REQUEST_FILENAME
    IS_SUBREQ

    Эти переменные полностью соответствуют названным похожим образом MIME-заголовкам HTTP, и переменным сервера Apache или полям struct tm систем Unix. Большинство из них документрованны в других местах руководства или в спецификации CGI. Те, что являются для mod_rewrite специальными включают:

    IS_SUBREQ
    Будет содержать текст если запрос выполняется в текущий момент как подзапрос, в другом случае. Подзапросы могут быть сгенерированны модулями которым нужно иметь дело с дополнительными файлами или URI для того чтобы выполнить собственные задачи.
    API_VERSION
    Это версия API модуля Apache (внутренний интерфейс между сервером и модулем) в текущей сборке сервера, что определено в include/ap_mmn.h. API версия модуля соответствует используемой версии Apache (для версии Apache 1.3.14, к примеру это 19990320:10), однако это в основном интересно авторам модулей.
    THE_REQUEST
    Полная строка HTTP запроса отправленная браузером серверу (т.е., GET /index.html HTTP/1.1>). Она не включает какие-либо дополнительные заголовки отправляемые браузером.
    REQUEST_URI
    Ресурс, запрошенный встроке HTTP запроса. (В примере выше, это было бы .)
    REQUEST_FILENAME
    Полный путь вфайловой системе сервера кфайлу или скрипту соответствующим этому запросу.

Специальные примечания:

  1. Переменные SCRIPT_FILENAME и REQUEST_FILENAME содержат одинаковые значения, т.е., значение поля filename внутренней структуры request_rec сервера Apache. Первое имя это просто широко известное имя переменной CGI в то время как второе это постоянная копия REQUEST_URI (содержащая значение поля uri структуры request_rec).
  2. Есть специальный формат: %{ENV:переменная} где переменная может быть любой переменной окружения. Это ищется вовнутренних структурах Apache и(если там нет) спомощью вызова getenv() из процесса Apache сервера.
  3. Есть специальный формат: %{HTTP:заголовок} где заголовок может быть любым именем HTTP MIME-заголовка. Это ищется вHTTP запросе. Пример: %{HTTP:Proxy-Connection} значение HTTP заголовка Proxy-Connection:.
  4. Есть специальный формат %{LA-U:переменная} опережающих запросов которые производятся внутренним (основанном наURL) подзапросом для определения конечного значения переменной. Используйте это когда вы хотите использовать переменную для преобразований, которая реально определяется позднее, в какой-либо фазе API, и таким образом недоступна на данном этапе. Для примера когда выхотите преобразовать соответственно переменной
    REMOTE_USER
    из контекста сервера (файл httpd.conf) вы должны использовать %{LA-U:REMOTE_USER} потому что эта переменная устанавливается в фазах авторизации которые идут после фазы трансляции URL в которой иработает mod_rewrite. Сдругой стороны, попричине реализации работы mod_rewrite в контексте каталога (файл .htaccess) через Fixup фазу API и из-за того, фазы авторизации идут до этой фазы, вы просто можете там использовать %{REMOTE_USER}.
  5. Есть специальный формат: %{LA-F:переменная} который создает внутренний (основанный на имени файла) подзапрос для определения конечного значения переменной. В основном это тоже самое что и формат LA-U приведенный выше.

Условие это шаблон условия, т.е., какое-либо регулярное выражение применяемое к текущему экземпляру

СравниваемаяСтрока, т.е., СравниваемаяСтрока просматривается на поиск соответствия Условие.

Помните: Условие это perl совместимое регулярное выражение с некоторыми дополнениями:

  1. Вы можете предварять строку шаблона префиксом ! (восклицательный знак) для указания несоответствия шаблону.
  2. Есть некоторые специальные варианты Условие. Вместо обычных строк с регулярными выражениями можно также использовать один из следующих вариантов:
    • <Условие (лексически меньше)
      Условие считается простой строкой и лексически сравнивается с СравниваемаяСтрока. Истинно если СравниваемаяСтрока лексически меньше чем Условие.
    • >Условие (лексически больше)
      Условие считается простой строкой и лексически сравнивается с
      СравниваемаяСтрока
      . Истинно если СравниваемаяСтрока лексически больше чем Условие.
    • =Условие (лексически равно)
      Условие считается простой строкой и лексически сравнивается с СравниваемаяСтрока. Истинно если СравниваемаяСтрока лексически равно Условие, т.е. эти две строки полностью одинаковы (символ всимвол). Если Условие имеет вид "" (два знака дюйма идущих подряд) это сравнивает СравниваемаяСтрока с пустой строкой.
    • -d (является ли каталогом)
      СравниваемаяСтрока считается путем, проверяется существование этого пути и то что этот путь является каталогом.
    • -f (является ли обычным файлом)
      СравниваемаяСтрока считается путем, проверяется существование этого пути иточто этот путь является обычным файлом.
    • -s (является лиобычным файлом с ненулевым размером)
      СравниваемаяСтрока считается путем, проверяется существование этого пути и то что этот путь является обычным файлом, размер которого больше нуля.
    • -l (является лисимволической ссылкой)
      СравниваемаяСтрока считается путем, проверяется существование этого пути и то что этот путь является символической ссылкой.
    • -F (проверка существования файла через подзапрос)
      Проверяет через все списки контроля доступа сервера, существующие в настоящий момент, является ли СравниваемаяСтрока существующим файлом, доступным по этому пути. Для этой проверки используется внутренний подзапрос, поэтому используйте эту опцию с осторожностью — это отрицательно сказывается напроизводительности сервера!
    • -U (проверка существования URL через подзапрос)
      Проверяет через все списки контроля доступа сервера, существующие в настоящий момент, является ли СравниваемаяСтрока существующим URL, доступным по этому пути. Для этой проверки используется внутренний подзапрос, поэтому используйте эту опцию с осторожностью — это отрицательно сказывается напроизводительности сервера!

    Замечание

    Все эти проверки также могут быть предварены префиксом восклицательный знак (‘!’) для инвертирования их значения.

Дополнительно вы можете устанавливать специальные флаги для Условие добавляя

[flags]

третьим аргументом в директиву RewriteCond. Flags список следующих флагов разделенных запятыми:

Пример:

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

RewriteCond  %{HTTP_USER_AGENT}  ^Mozilla.*
RewriteRule  ^/$   /homepage.max.html  [L]

RewriteCond  %{HTTP_USER_AGENT}  ^Lynx.*
RewriteRule  ^/$   /homepage.min.html  [L]

RewriteRule  ^/$   /homepage.std.html  [L]

Интерпретация: Если у вас Netscape Navigator (который идентифицируется как ‘Mozilla’), вы выдаете максимально навороченную страницу, с фреймами, и т.д. Если у вас Lynx (текстовый браузер), вы выдаете наименее навороченную страницу, без рисунков, таблиц и т.д. Если любой другой браузер, выдаете стандартную страницу.

Шпаргалка по .htaccess – База знаний Timeweb Community

Шпаргалка по .htaccess

Это не мануал, здесь собраны наиболее часто используемые настройки .htaccess, своего рода сборник подсказок.

Для чего нужен .htaccess

.htaccess позволяет создать собственную конфигурацию управлением сервера Апач в директориях или настройках хостинга.

Правила .htaccess распространяются на все директории, где расположен файл, кроме директорий, где расположен собственный .htaccess.

Файл .htaccess считывается сервером Апач при каждом обращении, поэтому все изменения входят в силу сразу, после изменения.

Глобальные настройки сервера Апач могут содержать запрет на исполнение некоторых команд, обычно это вызывает ошибку 500. Также подобную ошибку может вызывать неправильный синтаксис или ошибка, например пропуск пробела.

Запрет доступа для определенных IP-адресов или диапазонов IP-адресов

Запрет доступа с IP-адреса 123.123.123.123.


Order Deny,Allow
Deny from 123.123.123.123

Если не указывать последние цифры адреса, то запрет будет распространяться на весь диапазон 123.123.123.0 — 123.123.123.255.


Order Deny,Allow
Deny from 123.123.123

Разрешаем доступ только с определенных IP-адресов


Order Deny,Allow
Deny from all
Allow from 123.123.123.123

Принудительное задание кодировки

Иногда требуется очистка кэша браузера.

Отмена перекодировки сервером

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

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


ErrorDocument 404 http://site.ru/error/404.html
ErrorDocument 403 http:// site ru/error/403.html
ErrorDocument 401 http:// site.ru/error/401.html
ErrorDocument 500 http:// site.ru/error/500.html

Строка ErrorDocument 404 http://site.ru/error/404.html указывает, что при ошибке 404 будет показан файл 404.html, который должен находиться в корне директории сайта. Если файл расположен в другой директории, измените путь к файлу или ссылке.

Редиректы

Редирект на .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]

Редирект с www на без www


RewriteCond %{HTTP_HOST} ^www\.site\.ru$ [NC]
RewriteRule ^(.*)$ http://site.ru/$1 [R=301,L]

Редирект без www на www


RewriteCond %{HTTP_HOST} ^site.ru$ [NC]
RewriteRule ^(.*)$ http://www.site.ru/$1 [R=301,L]

Склейка доменов

Пример, у вас несколько доменов, но посетитель должен переправляться на один.


RewriteCond %{HTTP_HOST} !^site.ru$
RewriteRule ^(.*) http://site.ru/$1 [R=301,L]

Редирект со старых статических url на новые

Пример редирект со страницы http://site.com.ru/id=21.


RewriteCond %{QUERY_STRING} ^id=21$
RewriteRule ^/page.php$ http://site.ru/news.html [L,R=301]

Защита от хотлинка

Если вы хотите запретить вставку изображений с сайта по прямой ссылке.

Вместо site.ru укажите адрес сайта, jpg|jpeg|png|gif — расширение запрещенных изображений, images.jpg – изображение которое будет показываться, если картинка находится не в корне сайта, укажите полный путь.


RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?site.ru [NC]
RewriteRule \.(jpg|jpeg|png|gif)$ images.jpg [NC,R,L]

Защита от брутофорса

Разрешаем доступ к директории administrator только по протоколу HTTP, что отсеет некоторых ботов. Для каждой CMS нужно указать свой адрес, например wp-login, wp-admin и так далее.


RewriteCond %{REQUEST_URI} ^/administrator\.php$
RewriteCond %{THE_REQUEST} HTTP/1\.0
RewriteRule ^(.*)$ - [F,L]

Бытует легенда, что происхождения названия сервера Апач происходит не от названия индейского племени. Когда сервер был еще в самом начале пути, группа энтузиастов небольшие дополнения к коду, патчи (англ – patch), и «a patchy server» превратилось в Апач, а знаменитое перо на логотипе появилось позже.

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

Статья писалась эпизодическими «набегами», так что если увидите ошибку, поправьте.

Мой аккаунт на Marketplace — https://timeweb.com/ru/community/marketplace/bashkov-vladislav, обращайтесь

301 редирект c http на https через htaccess в 2020

301 редирект с http на https позволяет осуществить полный переезд сайта на защищенный протокол после установки SSL-сертификата.

Как сделать 301 редирект с http на https через htaccess

При переезде сайта с http на https (установка SSL-сертификата) потребуется код, который не требует дополнительных модификаций:

RewriteEngine On

RewriteBase /

RewriteCond %{HTTP:X-HTTPS} !1

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

Второй метод осуществляет перенос с http://domain.ru на https://domain.ru:

RewriteEngine On

RewriteBase /

RewriteCond %{HTTP:X-HTTPS} !1

RewriteCond %{HTTP_HOST} ^domain\.ru$

RewriteRule ^(.*)$ https://domain.ru/$1 [R=301,L]

Третий способ выполняет аналогичную функцию, но отключает перенаправление для robots.txt:

RewriteEngine On

RewriteBase /

RewriteCond %{HTTP:X-HTTPS} !1

RewriteCond %{REQUEST_URI} !robots.txt

RewriteRule ^(.*)$ https://domain.ru/$1 [R=301,L]

В 4-й версии конечным пунктом для пользователя станет https://www.domain.ru:

RewriteEngine On

RewriteBase /

RewriteCond %{HTTP:X-HTTPS} !1

RewriteCond %{HTTP_HOST} ^domain\.ru$

RewriteRule ^(.*)$ https://www.domain.ru/$1 [R=301,L]

Позволяет сделать форвардинг с http://www.poddomen.domain.ru на https://poddomen.domain.ru:

Options +FollowSymLinks

RewriteEngine On

RewriteCond %{HTTP_HOST} ^www\.poddomen\.domain\.ru$ [NC]

RewriteRule ^(.*)$ https://poddomen.domain.ru/$1 [R=301,L]

RewriteBase /

RewriteCond %{HTTP:X-HTTPS} !1

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

Последняя версия, дающая возможность сделать связь между http://poddomen.domain.ru на https://www.poddomen.domain.ru:

Options +FollowSymLinks

RewriteEngine On

RewriteCond %{HTTP_HOST} ^poddomen\.domain\.ru$ [NC]

RewriteRule ^(.*)$ https://www.poddomain.domain.ru/$1 [R=301,L]

RewriteBase /

RewriteCond %{HTTP:X-HTTPS} !1

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

Перенаправление с https на http

При необходимости сделать обратную интеграцию и перейти на незащищенную версию протокола можно воспользоваться:

RewriteEngine On

RewriteBase /

RewriteCond %{HTTP:X-HTTPS} 1 [NC]

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

Как это сделать?

Для того, чтобы выполнить правило, потребуется посетить административную панель хостинга (или же зайти через FTP), где в корневой папке сайта лежит файл htaccess.

Файл htaccess на сервереФайл htaccess на сервере

Вводим нужное нам правило.

прописанный редирект в htacessпрописанный редирект в htacess

Как проверить работу 301 редиректа?

Для этого можно использовать инструмент проверки ответа сервера Яндекса:

https://webmaster.yandex.ru/tools/server-response/

Здесь вводим адрес первой страницы и видим следующее:

Проверка 301 редиректа через сервисПроверка 301 редиректа через сервис

Как видим правило применилось и работает корректно.

Apache переадресация сайта c www на без www и с HTTP на HTTPS протокол

Все более широкое внедрение протокола HTTPS поставило несколько новых задач перед разработчиками и системными администраторами. Таких, как необходимость редиректа с http на https.

Ниже я покажу, как перенаправить сайт с www на без-www (или наоборот) и с http на https, используя конфигурацию сервера Apache. Чтобы стало понятнее, конфигурация будет перенаправлять следующие имена хостов:

http://example.com
http://www.example.com
https://example.com

на

Также я покажу небольшое изменение для перенаправления без-WWW на версию с WWW, если вы предпочитаете WWW.

Перед тем, как сделать редирект с https на http, добавьте следующее правило перенаправления в файл конфигурации Apache (если у вас есть доступ к нему), либо в файл .htaccess, расположенный в корневом каталоге вашего сайта:

RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www. [NC]
RewriteCond %{HTTP_HOST} ^(?:www.)?(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]

Если вместо example.com вы хотите использовать по умолчанию URL www.example.com, то просто измените третью и пятую строки:

RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www. [NC]
RewriteCond %{HTTP_HOST} ^(?:www.)?(.+)$ [NC]
RewriteRule ^ https://www.%1%{REQUEST_URI} [L,NE,R=301]

Попробуем разобраться, как работает эта конфигурация htaccess редиректа http на https. Это поможет внести необходимые изменения:

Первая строка позволяет Apache запустить механизм преобразования http-ссылок, необходимый для выполнения перенаправления:

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www. [NC]

Эти две строки — условия перенаправления, они используются для определения того, должен ли запрос быть перенаправлен. Если любое из этих двух условий возвратит true, то Apache выполнит перенаправление, поскольку условия соединяются с помощью [OR].

Первое условие определяет, использует ли запрос URL не-HTTPS. Второе условие определяет, использует ли запрос URL www. Заметьте, я использовал www.а не www., потому что образец является регулярным выражением и точка здесь используется для экранирования. Следовательно, ее нужно оставить:

RewriteCond %{HTTP_HOST} ^(?:www.)?(.+)$ [NC]

Четвертая строка — она соответствует имени хоста входящего запроса, и разделяет его на www часть (если таковая имеется), и остальную часть имени хоста. Мы будем ссылаться на нее позже с помощью %1 в RewriteRule.

Если вы знаете имя хоста заранее, то можно улучшить правило редиректа с http на https, встроив URL и пропустив это условие (пример ниже):

RewriteRule ^ https://www.%1%{REQUEST_URI} [L,NE,R=301]

RewriteRule – центральный элемент перенаправления. С помощью этой строки мы предписываем Apache перенаправить любой запрос на новый URL, который состоит из:

  • https: // WWW;
  • %1: Ссылка на без-WWW часть хоста;
  • %{REQUEST_URL}: URL-запрос, без имени хоста.

Все эти маркеры соединены друг с другом, и представляют собой конечный URL перенаправления. В конце мы добавляем три флага:

  • NE — чтобы не выйти из специальных символов;
  • R=301 — использовать HTTP статус 301 редиректа;
  • L — прекратить обработку других правил, и немедленно перенаправить.

В моём примере htaccess редиректа http на https используется дополнительная строка RewriteCond, чтобы извлечь имя хоста, а не подставлять имя в правило. Если чувствуете, что для вас это — потеря производительности, то можете встроить хост непосредственно в правило:

RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www. [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [L,NE,R=301]

В данной статье представлена простая конфигурация перенаправления WWW и не-HTTPS запросов для домена сайта. Таким образом можно избежать проблем с дублированием контента в поисковых системах.

Данная публикация представляет собой перевод статьи «Apache redirect www to non-www and HTTP to HTTPS» , подготовленной дружной командой проекта Интернет-технологии.ру

Как сделать редиректы в htaccess

Как сделать seo редиректы на www или без него, добавление/удаление расширений у страниц.

1

Редирект на www

RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{HTTP_HOST} !^www.
RewriteRule (.*) http://www.%{HTTP_HOST}/$1 [R=301,L]

# Для https: 
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{HTTP_HOST} !^www.
RewriteRule (.*) https://www.%{HTTP_HOST}/$1 [R=301,L]

2

Удалить www

RewriteCond %{HTTP_HOST} ^www\.(.*) [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

# Для https: 
RewriteCond %{HTTP_HOST} ^www\.(.*) [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]

3

Добавление слеша в конец URL

RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !\.xml
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*[^/])$ $1/ [L,R=301]

Иногда не работает с кириллическими доменами, возможен еще вариант:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !\.xml
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://xn--80aswg.xn--p1ai/$1/ [L,R=301]

# Для https: 
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !\.xml
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://xn--80aswg.xn--p1ai/$1/ [L,R=301]

4

Удаление слеша в конце URL

RewriteCond %{REQUEST_URI} ^(.*)/$
RewriteRule ^(.*)/$  /$1 [R=301,L]

5

Удаление повторяющихся слешей

Если нужно убрать несколько слешей, например https://example.com/sections///////// или https://example.com/////////sections/.

RewriteCond %{THE_REQUEST} ([^\s]*)\/{2,}(\?[^\s]*)?
RewriteRule (.*) %1 [R=301,L]

6

Редирект с index.php

RewriteCond %{THE_REQUEST} ^.*/index.php 
RewriteRule (.*) http://%{HTTP_HOST} [R=301,L]

# Для https: 
RewriteCond %{THE_REQUEST} ^.*/index.php 
RewriteRule (.*) https://%{HTTP_HOST} [R=301,L]

7

Редирект .htm на .html

RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} \.htm$
RewriteRule ^(.*)\.htm$ $1.html [R=301,L]

8

Замена .html на слеш

RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} \.html$
RewriteRule ^(.*)\.html$ $1/ [R=301,L]

9

Если расширение не .html то 404

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !\.html$
RewriteRule ^(.*)$ index.php?route=404 [L,QSA]

10

Редирект на другой домен

RewriteEngine On
RewriteCond %{HTTP_HOST} ^site\.com
RewriteRule ^(.*)$ http://site.ru/$1 [R=301,L]

Шпаргалка по модулю mod_rewrite сервера Apache

Шпаргалка по модулю mod_rewrite сервера Apache

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

Модуль mod_rewrite — это модуль сервера Apache, предоставляющий мощный функционал для выполнения различных преобразований над URL, которые Apache выполняет на лету. Этот модуль содержит синтаксический анализатор URL с возможностью применения регулярных выражений. Также модуль позволяет использовать при анализе URL не только сам URL, но и разные другие источники данных, как например переменные сервера, переменные окружения, HTTP заголовки, время и даже(!) запросы к внешним базам данных в разных форматах. Практически это значит, что получив URL Вы сможете синтаксически разобрать его на любые части как вы этого захотите. Затем вы сможете выполнить сравнения, с применением множества условий, любых частей вашего URL с большим количеством доступных параметров как из окружения сервера Apache так и ваших собственных, подставленных напрямую, так и полученных из баз данных. Затем, в зависимости от результатов сравнения, вы сможете выполнить различные преобразования над текущей строкой URL (с которой модуль в текущий момент работает) и даже сгенерировать части строки URL. Как следствие, на выходе вы можете получить новую строку URL, и теперь сервер Apache уже будет искать запрошенную страницу не по первоначальному URL, а уже по новому измененному вами URL. В добавок к этому вы можете определить или переопределить поведение apache при обработки вашего нового URL.  При помощи специальных флагов вы можете задать для apache как ему следует обрабатывать этот новый URL. Все эти действия в результате приведут или к внутренней обработке нового URL, или к внешнему перенаправлению запроса, или даже к прохождению его через внутренний прокси модуль –то все определите вы. Далее приведены некоторые из возможных поведений при обработке нового URL. Так как новый URL может быть любым — как внутренним, так и внешним, то произойдет внутренне или внешнее перенаправление с первоначального URL на ваш конечный преобразованный URL. При внутреннем перенаправлении, когда ваш новый URL ссылается на тот же сайт, что и в первоначальном URL, вы можете выполнить внутреннее перенаправление не изменяя строку адреса в браузере клиента, т.е. клиент даже не заметит, что на сервере произошло внутреннее перенаправление (обработка) его запроса, и он обратился по одному URL, а в действительности ответ он получил от другого URL. Для клиента будет виден, в этом случае, только URL по которому он обратился, о наличии внутреннего перенаправления он сможет только догадываться. Такое внутреннее перенаправление достаточно распространенный подход для систем управления контентом, когда все запросы к файлам PHP сайта перенаправляются на главный index.php системы управления контентом. Также внутренние перенаправление можно выполнить сделав изменение URL в браузере клиента с отправкой ему кода заголовка перенаправления (redirect), например, кода 301 Moved Permanently — постоянное перенаправление. Когда же новый, преобразованный вами URL будет уже ссылаться на другой сайт, то произойдет внешнее перенаправление. Также вы можете направить запрос на внутренний прокси сервер. Вы также можете определить и другие варианты поведения для нового URL, например, отказать в выдачи файла и т.п., вариантов поведения которые можно задать специальными флагами достаточно, чтобы обеспечить все необходимые варианты.

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


Вот эти постулаты:

•    Модуль оперирует с полными URL (включая path-info) и в контексте сервера apache и в контексте каталога (.htaccess) и даже может генерировать части строки запроса в качестве результата.  Практически это значит следующее,  если, например, вы используете директивы модуля mod_rewrite в файле .htaccess, расположенном в корне вашего сайта, то исходный URL (до каких либо преобразований) будет начинаться от корня вашего сайта.

•    Правило преобразования URL (RewriteRule директива) это условие и правило одновременно. Если вы посмотрите на синтаксис RewriteRule директивы, то увидите, что она содержит условие, которому должен соответствовать текущий URL, что бы это правило преобразования начало выполняться, и само по себе правило преобразования (это то как изменить текущий URL).  Здесь под словом правило подразумевается некое выражение, согласно которому будет выполнено изменение URL. Я, для наглядности, что бы избежать путаницы со словом «правило» сказал бы,  что RewriteRule содержит условие и алгоритм изменения URL, который называют правилом изменения URL.  Т.е. что бы правило начало выполняться (именно начало, т.к. по ходу выполнения возможны разные варианты и не всегда это приведет к указанному в правиле преобразованию URL) должно выполняться заданное в правиле условие для этого URL. Иными словами, правило преобразования срабатывает и начинает выполняться только если текущий URL соответствует условию из этого правила. Здесь можно провести аналогию для директивы RewriteRule как бы с подпрограммой, которая запускается по условию и выполняет некие манипуляции, в том числе и изменение URL. Но результат выполнения этой подпрограммы не всегда изменение URL. Т.е. нужно понимать, что запушенное правило преобразования не обязательно приведет к изменению URL, по ходу его работы возможны разные варианты исполнения правила, которые задаются дополнительными условиями. Об этом следующий пункт.

•    К правилу (RewriteRule) помимо условия, содержащегося в самом правиле (это условие запускает исполнение самого правила) можно задать дополнительные условия при помощи директив RewriteCond.  Дополнительных условий может быть несколько (несколько строк с RewriteCond директивами). Вот тут начинается разрыв шаблона. Но не пугайтесь, сейчас все объясню.  Зачем нужны дополнительные условия и почему их не вставить в правило сразу? Тут дело в том, что условие в правиле, если оно выполняется, только запускает процесс исполнения правила, а дополнительные условия начинают проверяться только в ходе исполнения правила и позволяют управлять ходом исполнения этого правила! Таким образом дополнительные условия позволяют уже в процессе выполнения правила определить выполнить ли в конечном итоге преобразования этого несчастного URL или нет. И, еще один разрыв шаблона, записываются эти дополнительные условия (RewriteCond)  не после самого правила (как было бы логично), а перед правилом(RewriteRule). Это выглядит нелогично и когда начинаешь разбираться с этим в первый раз сбивает с толку. Но такая запись дополнительных условий перед правилом объясняется историческими причинами. Просто так сложилось. Да, это не логично, но примите это как данность и запомните, что дополнительные условия (RewriteCond директивы) записываются ПЕРЕД их правилом (RewriteRule), а не после, и начинают эти условия проверяться только тогда, когда правило запустилось на выполнение. О логике исполнения именно дополнительных условий ниже.

•    Понятие текущего URL. Здесь под «текущим» подразумевается значение URL, когда проверяется и применяется текущее правило. Этот URL не обязательно совпадает с первоначально запрошенным URL, потому что любое количество правил возможно уже были применены к нему и соответственно преобразовали изначальный URL, т.к. этот модуль может выполнять несколько последовательно следующих друг за другом преобразований URL. Это значит, что если вы указали несколько правил (RewriteRule) для преобразования URL, то все те правила, которые соответствуют указанным в них условиям, будут выполнять изменения (преобразования) URL последовательно от предыдущего правила к следующему правилу. Отсюда очень важный постулат: первичный URL, который, так сказать, пошел по этапам обработки будет меняться от одного выполненного правила к другому, и каждое последующее правило будет начинать работать (проверять на условие и изменять) уже НЕ с первичной строкой URL, а уже с той измененной строкой, которая получилась на выходе от применения предыдущего правила(преобразования). Это очень важно понимать, что каждое последующее правило преобразования работает НЕ с первичной строкой URL, а работает со строкой URL уже преобразованной предыдущим исполненным правилом (именно исполненным правилом, т.е. правилом которое последним выполнило преобразование).

•    Порядок расположения правил (RewriteRule) в файле имеет значение. Как видите из выше описанного, порядок расположения правил обработки URL имеет важное значение, т.к. URL передается от правила к правилу.  Также Порядок правил в наборе важен еще потому, что механизм преобразований обрабатывает их по следующей логике. Сначала механизм преобразований просматривает последовательно весь набор правил строчка за строчкой (RewriteRule директивы) и когда он встречает правило (RewriteRule) условие из которого применительно к текущему URL является истинным, то механизм преобразований начинает исполнять это правило. Если же условие из правила (RewriteRule) ложно для текущего URL, то механизм преобразования НЕ исполняет это правило, а переходит к следующему правилу.

•    Логика исполнения правила (RewriteRule). Исполнение же правила подразумевает следующие действия: первым делом механизм преобразования выполняет поиск дополнительных условий для этого правила (RewriteCond директивы). Помним, что по историческим причинам дополнительные условия находятся перед правилами(RewriteRule). Если дополнительные условия для этого правила отсутствуют, то механизм преобразований тупо выполняет указанное в правиле преобразование текущего URL и переходит к следующему правилу. Однако если для исполняемого правила (RewriteRule) существуют дополнительные условия, указанные ПЕРЕД НИМ в директивах RewriteCond, то запускается внутренний цикл для обработки этих дополнительных условий в том порядке, в котором они перечислены, сверху вниз. Если из имеющихся для правила дополнительных условий хотя бы одно условие НЕ выполняется это приводит к остановке запущенного процесса исполнения правила, и преобразование над URL, заданное в правиле, НЕ выполняется. Что бы запущенное на исполнение правило выполнилось до конца и изменило URL, необходимо, что бы выполнились ВСЕ дополнительные условия, указанные в директивах RewriteCond перед этим правилом! Тут нужно дополнительно пояснить, что директивы RewriteCond по умолчанию объединены между собой оператором AND в одно составное условие. Просто этот оператор(AND) не записывается по умолчанию. От сюда и такая логика, что нужно, что бы все дополнительные условия были истинными (т.к. они объедены через AND) для удачного завершения преобразования URL. Однако директивы RewriteCond можно объединить условием OR при помощи флагов (см. синтаксис директивы). Про это нужно помнить, при задании дополнительных условий.

•    После исполнения правила можно дополнительно переопределить алгоритм обработки измененного URL сервером apache. Здесь имеется в виду то, что вы можете после изменения URL при помощи специальных флагов указать для apache нужные вам действия, например отказать в выдачи файла, или выполнить ридирект на новый URL.

•    Нужно помнить,  что mod_rewrite является частью apache,  это значит, что вы можете применить его функционал (директивы) на разных уровнях конфигурации apache. На глобальном уровне, путем записи директив в главный конфиг apache или в конфиги подключаемые к нему, на уровне виртуального хоста путем добавления директив в файлы конфигурации виртуальных хостов, и на уровне каталога путем добавления директив в файл. htaccess.

Логическая схема исполнения правила (RewriteRule)

Шпаргалка по модулю mod_rewrite сервера Apache


Теперь, когда мы рассмотрели главные постулаты и логику обработки правила, рассмотрим синтаксис директив.


Синтаксис директивы RewriteRule:

RewriteRule Шаблон Подстановка [Флаги]

Пример:

RewriteRule ^(.*)$ index.php?/$1 [L,QSA]

Где:

1.    RewriteRule  – это название директивы – правила.
2.    Шаблон — это как раз то условие, выполнение которого запускает исполнение правила. Это условие — Шаблон представляет собой perl совместимое регулярное выражение, которое применяется к текущему URI без query string с GET параметрами.
3.    Подстановка – это как раз тот алгоритм изменения URL, т.е. правило изменения (преобразования) URL.
4.    [Флаги] подстановки — Третий аргумент директивы RewriteRule.

[Флаги] RewriteRule Flags — это разделённый запятыми, заглавные спец символы, заключенные в квадратные скобки. Флаги дополняют преобразование URL.

В параметрах Подстановка из RewriteRule и СравниваемаяСтрока из RewriteCond доступны для использования подвыражения (то что заключено в скобки в РВ) — части регулярного выражения. Обращаться к подвыражениям в условиях RewriteCond нужкно как %N и в подвыражений в правилах RewriteRule как $N. Здесь N — это номер подвыражения по порядку в строке с регулярным выражением.

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

Теперь давайте разберем пример правила RewriteRule:

RewriteRule ^(.*)$ index.php?/$1 [L,QSA]

1.    ^(.*)$ — это Шаблон, регулярное выражение которое применится к текущему URI (без query string с GET параметрами). Кто знаком с регулярными выражении, сможет прочитать его так: искать в текущей строке URI от начала строки(знак ^) до конца строки(знак $) любой символ (знак .) в количестве от нуля до бесконечности (знак *). Так как в этом РВ есть скобки(), то та часть URI которая будет соответствовать условию в скобках будет захвачена в переменную подстановки $1, которую мы потом сможем использовать в Подстановке или в СравниваемаяСтрока(это в директиве RewriteCond, о ней ниже).
2.     index.php?/$1Подстановка – это собственно и есть правило преобразования URL. Запись index.php?/$1 означает, что строка нового, преобразованного URL должна быть составлена из двух частей, где первая часть строки это постоянное значение index.php?/, а вторая часть строки это значение из переменной подстановки $1. Тут мы вспоминаем что в $1 храниться та часть URL которая соответствовала части регулярного выражения в скобах из параметра Шаблон. В итоге мы получаем преобразованный URL вида index.php?/URL_по которому обратились. По другому сказать так, что для всех запросов выполняется внутренне перенаправление на файл index.php.
3.    [L,QSA]флаги, где ‘last|L‘ — последнее правило что означает — остановить процесс преобразования на этом месте и не применять больше никаких следующих правил преобразований для URL.

Флаг ‘qsappend|QSA‘ — значит добавить в конец нового URI исходную строку GET параметров запроса QUERY_STRING, которая содержится в серверной переменной %{QUERY_STRING}. Этот флаг указывает механизму преобразований на добавление, а не замену, строки параметров GET запроса из URI к строке Подстановка. Дело в том, что если ваш начальный URI содержит query string с GET параметрами, например: /pages/123?one=two, то по умолчанию RewriteRule преобразование отбрасывает эту query string с GET параметрами от URI. Если же добавить к RewriteRule флаг [QSA], то тогда первоначальная query string с GET параметрами будет добавлена в конец нового URI, преобразованного в RewriteRule.

Пример:

RewriteRule "/pages/(.+)" "/page.php?page=$1" [QSA]

В примере, при наличии [QSA] флага, запрошенный URI вида /pages/123?one=two будет преобразован в /page.php?page=123&one=two. Однако, без использования [QSA] флага, он уже будет преобразован в /page.php?page=123, где уже будет отсутствовать оригинальная первичная query string с GET параметрами.

 

Ну вот мы разобрали синтаксис простого примера директивы RewriteRule, теперь дело за синтаксисом директивы RewriteCond

Синтаксис RewriteCond:

RewriteCond СравниваемаяСтрока Условие [flags]

Где:
1.    СравниваемаяСтрока это строка которая будет проверятся на соответствие выражению, указанному в параметре Условие. СравниваемаяСтрока может, к примеру, содержать часть или весь URL. Подставить в параметр СравниваемаяСтрока часть URL можно при помощи переменных подстановки, которые были созданы в соответствующем RewriteRule. Также параметр СравниваемаяСтрока может содержать различные переменные (Server-Variables) из окружения web сервера Apache, например:

  • %{REQUEST_URI} — Строка URI запроса — это часть от полного URL без доменного имени и GET параметров вида «/pages/page/1/»;
  • %{HTTP_HOST} — Строка с доменным именем, например: «andew.ru» или «www.andew.ru»;
  • %{QUERY_STRING}    Строка GET параметров ,например, «?page=123&one=two».

Но в конечном итоге, после всех манипуляций, параметр СравниваемаяСтрока это всегда строка, которая передается в выражение из параметра Условие для проверки на истинность.

2.    Условие – это логическое выражение по которому проверяется параметр СравниваемаяСтрока. Часто в Условие применяют РВ.

3.    [flags] — третьим аргументом в директиве RewriteCond. Флаг позволяет задать дополнительные опиции, например, можно установить логику объединения правил RewriteCond через логическое И [AND] (по умолчанию) или через логическое ИЛИ [OR], или/и можно задать, будет ли сравнение в условии RewriteCond выполнятся с учетом регистра или без учета регистра, и много другое. Некоторые наиболее часто используемые флаги в условиях 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]

В примере1 мы видим, что директиве RewriteRule соответствует 4-е дополнительных условия (RewriteCond). Если правило начнет исполняться (об этом см. синтаксис правила), то механизм преобразований начнет по очереди обходить каждое из этих дополнительных условий, начиная с первого. Помним, что дополнительные условия стоят перед правилом. Если все дополнительные условия выполняться, произойдет преобразование URL. Если хотя бы одно дополнительное условие не выполниться, исполнение правила будет остановлено и преобразования URL не произойдет. Тут нужно заметить, что дополнительные условия объединены по умолчанию через оператор AND, хотя он явно не указан. Поэтому то и необходимо исполнение всех дополнительных условий.


Теперь разберем первое дополнительное условие из примера1:

RewriteCond $1 !^(index\.php|images|robots\.txt|public) [NC]


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

Теперь давайте словами опишу блок директив из примера1.

Этот блок директив содержит одно правило преобразования URL и дополнительные условия для этого правила. Смысл этого блока – выполнить заданную проверку и преобразование URL. На словах это будет звучать так. Для любого URL запустить выполнение правила перезаписи URL. По ходу выполнение правила проверить что URL:
•    НЕ начинается как index.php или images или robots.txt или public – т.е. не начинается на открытые нами к прямому обращению файл и каталоги. Сравнение символов URL на соответствие в этом условии проводить без учета регистра.
•    НЕ заканчивается на .css или .js или … т.е. не является файлом к которым мы позволяем обращаться напрямую
•    НЕ является реальным файлом на диске
•    НЕ является реальной директорией на диске
Если все условия выполнились то сделать следующие преобразование URL – собрать итоговую строку URL из двух строк, где первая строка это “ index.php?/”, вторя строка это первоначальный URL. Флаг L – значит закончить на этом правиле все дальнейшие преобразования URL. Флаг QSA значит добавить значение из $1 к результирующей строке URL, а не заменить ее.
Вот такой получился блок обработки URL.

 

Пример2:

RewriteCond %{REMOTE_HOST} ^host1.* [OR]

RewriteCond %{REMOTE_HOST} ^host2.* [OR]

RewriteCond %{REMOTE_HOST} ^host3.*

RewriteRule …

Это пример демонстрирует как можно при помоши флага [OR] объединить дополнительные условия (RewriteCond). Тут надо заметить, что нет флага [AND], а директивы (RewriteCond) записанные без флагов [OR] по умолчанию объединяются условием [AND], хотя явно оператор AND не прописывается. Об этом нужно не забывать.

 

Пример корневого файла .htaccess для сайта:

#пример файла .htacces

AddDefaultCharset UTF-8
Options -Indexes +FollowSymLinks
DirectoryIndex index.php index.html

#Блок если нужно ограничить доступ по IP
# смотри статью "Контроль доступа клиента в Apache "
#Order Deny,Allow
#Deny from all
#Allow from 127.0.0.1 192.168.1 ...

#Блок правил для модуля mod_rewrite
<IfModule mod_rewrite.c>
  RewriteEngine On

  #переопределить корень сайта, станет как "/"
  RewriteBase /

  #Все с HTTP на HTTPS
  RewriteCond %{HTTPS} =off
  RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,QSA,L]
#или как: RewriteRule ^(.*)$ https://%{HTTP_HOST}%/$1 [R=301,QSA,L]

  #Все что не файл, не директория, не картинка и т.п. - то на index.php
  RewriteCond %{REQUEST_URI} !^/(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]
#или как: RewriteRule . /index.php [L] 

#hotlink защита НЕ забывайте про экранирование в РВ
RewriteCond %{HTTP_REFERER} !^$
    RewriteCond %{HTTP_REFERER} !^http://site\.ru/ [NC]
    RewriteCond %{HTTP_REFERER} !^https://site \.ru/ [NC]
    RewriteCond %{HTTP_REFERER} !^http://www\.site\.ru/ [NC]
    RewriteCond %{HTTP_REFERER} !^https://www\.site\.ru/ [NC]
    RewriteRule \.(jpeg|png|bmp|gif|jpg|js|css)$ - [F]
</IfModule>

*Распространенные форматы файлов: jpeg|png|bmp|gif|jpg|js|css|mp4|mp3|webm|m4a|ogg|ogv|swf|webp|avi|mov|mpeg|mpc|mpg|tif|tiff|vtt|flv|gz

 

RewriteRule \.(jpeg|png|bmp|gif|jpg|js|css)$ [F]—это значит что для URI заканчивающиеся на .расширение из скобок — ничего не изменять (тире после РВ как параметр Подстановка значит НЕ изменять URL), не перезаписывать URL и [F] значит отказать в выдаче файла.

Примеры:

#редирект с www.site.ru на site.ru без www
RewriteCond %{HTTP_HOST} ^www\.(.*) [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,QSA,L]

Выполняется проверка доменного имени, и если домен начинается с www, то работает правило: все, на http://%1/$1. Где %1 это домен без www из условия в RewriteCond, а $1 это URI  из самого RewriteRule правила.

#редирект с site.ru на www.site.ru
RewriteCond %{HTTP_HOST} ^(.*)$ [NC]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%1/$1 [R=301,QSA,L]
Простые редиректы
#Простой внешний редирект, можно применять
#без RewriteCond, только с RewriteRule
RewriteRule ^pages/page.* /about.html [R=301,QSA,L]
Внутренний реврайт
#Внутренний реврайт, т.е. просто перезапись URI
RewriteRule ^pages/page.* /about.html [L]
#еще
RewriteRule ^index.php$  /about-us/ [L]
Редирект на основе GET параметров
#Пример редиректа со страницы
#/?do=page&id=15 был редирект на /page/15/
RewriteCond %{QUERY_STRING} do=page [NC]
RewriteCond %{QUERY_STRING} id=(\d+) [NC]
RewriteRule .* /page/%1/? [R=301,L]
Редирект с обычной на мобильную версию сайта
RewriteCond %{HTTP_HOST} ^(.*)$ [NC]
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]
RewriteRule ^$  http://m.%1 [R=302,L]

Еще примеры правил можно посмотреть в статье Как написать .htaccess файл для сайта

 

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

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

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

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

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

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

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

Андрей Болдырев

Перенаправление / перезапись URL с использованием файла .htaccess

По умолчанию ваш сайт доступен как с www.example.com, так и с example.com. Поскольку Google наказывает за это из-за причин дублирования контента, вам следует ограничить доступ либо к www.example.com, либо к example.com. Некоторые ссылки могут выходить за рамки вашего веб-сайта и / или поисковые системы уже проиндексировали ваш веб-сайт по обоим адресам.

Ваш основной файл .htaccess находится в папке public_html.Чтобы узнать, как получить доступ к этому файлу, обратитесь к нашему руководству .htaccess.

Перенаправление на или из WWW


Как перенаправить все ссылки с www.example.com на example.com?

Создайте перенаправление 301, заставляя все HTTP-запросы использовать либо www.example.com, либо example.com:

  • Пример 1. Перенаправление с example.com на www.example.com:
      RewriteEngine On
    RewriteCond% {HTTP_HOST}! ^ Www.www.example.com $ [NC]
     
     
    указывает, что следующее правило срабатывает только тогда, когда http-хост (то есть домен запрашиваемого URL-адреса) не (- указан с «!») www.example.com.

    Знак $ означает, что хост заканчивается на www.example.com — в результате все страницы с www.example.com запускают следующее правило перезаписи. В сочетании с инверсивным «!» В результате каждый хост, который не является www.example.com, будет перенаправлен на этот домен.

    [NC] указывает, что хост http не чувствителен к регистру.(. *) $ содержит запрошенный URL без домена.

    Следующая часть http://www.example.com/$1 описывает цель правила перезаписи. Это наше «последнее» используемое доменное имя, где $ 1 содержит содержимое (. *).

    Следующая часть также важна, поскольку она выполняет 301 редирект за нас автоматически: [L, R = 301]. L означает, что это последнее правило в этом прогоне. После этой перезаписи веб-сервер вернет результат. R = 301 означает, что веб-сервер возвращает 301, постоянно перемещенный в запрашивающий браузер или поисковую систему.$ http://example.com/index.php [L, R = 301]

    Объяснение этого перенаправления .htaccess 301:

    Что делает этот код выше? Давайте посмотрим на Пример 1 — Перенаправление с example.com на www.example.com. Первая строка запускает модуль перезаписи. Следующая строка:

      RewriteCond% {HTTP_HOST}! Www.example.com $
     
     
    указывает, что следующее правило срабатывает только в том случае, если хост http (то есть домен запрашиваемого URL) не (- указан с «!») www.example.com.

    $ означает, что хост заканчивается на www.example.com — и в результате все страницы с example.com запускают следующее правило перезаписи. В сочетании с инверсивным «!» В результате каждый хост, который не является www.example.com, будет перенаправлен на этот домен.

    [NC] указывает, что хост http не чувствителен к регистру. Ускользает от «.» — потому что это специальный символ (обычно точка (.) означает, что один символ не указан).

    Последняя строка описывает действие, которое необходимо выполнить:

      RewriteRule ^ (.(. *) $ содержит запрошенный URL без домена.
    
     

    Следующая часть http://www.example.com/$1 [L, R = 301] описывает цель правила перезаписи - это «последнее» используемое доменное имя, где $ 1 содержит содержимое (. * ).

    Следующая часть также важна, поскольку она выполняет 301 редирект за нас автоматически: [L, R = 301]. L означает, что это последнее правило в этом прогоне. После этой перезаписи веб-сервер вернет результат. R = 301 означает, что веб-сервер возвращает 301, постоянно перемещенный в запрашивающий браузер или поисковую систему.

    Перенаправить посетителей на новый сайт

    У вас есть старый веб-сайт, доступный по адресу oldexample.com, и у вас есть новый веб-сайт, доступный по адресу newexample.com. Копирование содержимого старого веб-сайта на новый - это первый шаг, но что будет после этого? Вам следует сделать 301 перемещенное постоянное перенаправление со старого домена на новый - это легко и имеет некоторые преимущества:

    • Пользователи будут автоматически перенаправлены на новый домен - вам не нужно их сообщать.
    • Поисковые системы будут перенаправлены на новый домен, и вся соответствующая информация будет перемещена в новый домен (но это может занять некоторое время).
    • Google PageRank à ¢ â € žÂ будет перенесен в новый домен, а также другая внутренняя информация, которая используется для установки положения страниц на страницах результатов поисковой системы (serp) - например, TrustRank.

    Создайте перенаправление 301 для всех HTTP-запросов, которые идут в старый домен.

      RewriteEngine On
    RewriteCond% {HTTP_HOST}! Oldexample.(. *) $ http://www.newexample.com/$1 [L, R = 301]
     
     
    • Пример 1. Перенаправление с oldexample.com на www.newexample.com:
    Это полезно, когда вы используете www.newexample.com в качестве нового доменного имени (см. Также эту статью о перенаправлении доменов с www и без www). Если нет - используйте код примера 2.

    Как добавить косую черту в конце

    Некоторые поисковые системы удаляют косую черту в конце URL-адресов, которые выглядят как каталоги, например Yahoo делает это.Однако это может привести к проблемам с дублированным контентом, если один и тот же контент страницы доступен по разным URL-адресам. Apache дает дополнительную информацию в FAQ по Apache Server.

    Давайте посмотрим на пример: example.com/google/ проиндексирован в Yahoo как example.com/google, что приведет к появлению двух URL с одинаковым содержанием.

    Решение состоит в том, чтобы создать правило перезаписи .htaccess, которое добавляет завершающие косые черты к этим URL-адресам. Пример - перенаправьте все URL-адреса без косой черты на URL-адреса с косой чертой в конце:

      RewriteEngine On
    RewriteCond% {REQUEST_FILENAME}! -F
    Пример RewriteCond% {REQUEST_URI}!.(. *) $ http://example.com/$1/ [L, R = 301]
    
     
    
     
    Объяснение правила перезаписи добавления завершающей косой черты .htaccess:

    Первая строка сообщает Apache, что это код для механизма перезаписи модуля mod_rewrite Apache. Вторая строка устанавливает текущий каталог как корень страницы. Но самое интересное:
    RewriteCond% {REQUEST_FILENAME}! -F

    гарантирует, что существующие файлы не будут добавлены косой чертой. Вы не должны делать то же самое с каталогами, поскольку это исключит поведение перезаписи для существующих каталогов.(. *) $ http://example.com/$1/ [L, R = 301]
    выполняет 301 перенаправление на URL-адрес с добавленной косой чертой. Вам следует заменить example.com своим доменом. .

    Перенаправление и переопределение с помощью mod_rewrite

    Самый лучший способ решить эту проблему — вообще не использовать mod_rewrite, а скорее использует Redirect директива, размещенная на виртуальном хосте для неканонических имя (а) хоста.

     
      ServerName undesired.example.com
      ServerAlias ​​example.com notthis.example.com
    
      Перенаправить "/" "http://www.example.com/"
    
    
    
      ServerName www.example.com
     

    Вы также можете сделать это, используя директива:

     <Если "% {HTTP_HOST}! = 'Www.example.com '">
        Перенаправить "/" "http://www.example.com/"
     

    Или, например, чтобы перенаправить часть вашего сайта на HTTPS, вы может сделать следующее:

     <Если "% {SERVER_PROTOCOL}! = 'HTTPS'">
        Перенаправить "/ admin /" "https://www.example.com/admin/"
     

    Если по какой-либо причине вы все еще хотите использовать mod_rewrite — если, например, вам это нужно для работы с большим набором RewriteRules — вы можете использовать один из рецептов ниже./?(.*) «» http: //www.% {HTTP_HOST} / $ 1 «[L, R, NE]

    Эти наборы правил будут работать либо в конфигурации вашего основного сервера. или в файле .htaccess , помещенном в DocumentRoot на сервере.

    .

    mod rewrite — .htaccess — как заставить «www.» в общем виде?

    Переполнение стека
    1. Около
    2. Товары
    3. Для команд
    1. Переполнение стека Общественные вопросы и ответы
    2. Переполнение стека для команд Где разработчики и технологи делятся частными знаниями с коллегами
    3. работы Программирование и связанные с ним технические возможности карьерного роста
    4. Талант Нанимайте технических специалистов и создавайте свой бренд работодателя
    5. реклама Обратитесь к разработчикам и технологам со всего мира
    6. О компании
    .Безопасность

    — Как перенаправить все HTTP-запросы на HTTPS

    Переполнение стека
    1. Около
    2. Товары
    3. Для команд
    1. Переполнение стека Общественные вопросы и ответы
    2. Переполнение стека для команд Где разработчики и технологи делятся частными знаниями с коллегами
    3. работы Программирование и связанные с ним технические возможности карьерного роста
    4. Талант Нанимайте технических специалистов и создавайте свой бренд работодателя
    5. реклама Обратитесь к разработчикам и технологам со всего мира
    6. О компании
    .

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *