Найти тему
Mitup

Что такое htaccess, и для чего он нужен

Оглавление

Что такое файл «.htaccess»

Файл .htaccess – файл конфигурации сервера Apache. Служит для того, чтобы с помощью команд задавать настройки http-сервера для папок, отдельных страниц и пользователей. Подходит, когда необходимы точечные настройки для отдельных директорий.

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

Файл .htaccess находится в корневой папке сайта, а редактировать можно в любом текстовом редакторе. Изменения файла не требуют перезапуск сервера – они сразу вступают в силу.

Действие команд распространяется на документы, находящиеся с файлом в одной директории. Если во вложенной директории есть другой .htaccess, тогда уже он будет действовать на нее.

Правила для файла:

  • каждая команда начинается с новой строки;
  • после # можно добавить комментарий;
  • URL на кириллице, необходимо переводить на Punycode.

Основные спецсимволы:

-2

Основные переменные:

-3

Подробнее о переменных в официальной документации Apache.

Как прописать редирект при помощи .htaccess

Для прописывания редиректа устанавливаются 2 директивы:

  • RewriteCond – определяет условие, при котором происходит преобразование.
  • RewriteRule – задает правило перенаправления. Синтаксис: RewriteRule Шаблон Подстановка [flag], где # flag – необязательное поле, указывающее дополнительные опции

1. Редирект одной страницы на другую

Пример:

Redirect 301 /url1/ https://mitup.ru/url2

где:

  • /url1/ — адрес страницы, с которой перенаправлять. Адрес нужно указывать от корневой директории сайта, без указания протокола и домена.
  • https://mitup.ru/url2 — адрес страницы, на которую нужно редиректить. Указывать нужно полный адрес — с протоколом и доменом.

2. Перенаправление с www на без www

Пример (с www.mitup.ru на mitup.ru):

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

где:

  • RewriteCond %{HTTP_HOST} ^www\.(.*) [NC]

{HTTPS_HOST} – переменная, которую будем анализировать и сверять с подстрокой mitup.ru внутри RewriteCond.

^ – начало строки.

www\.(.*) – с какого символа/вложенности будем применять правило. В данном случае с www.

[NC] – регистронезависимая проверка.

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

(.*)$ – с какого символа/вложенности будем применять правило. Где $ – подстановка символов.

http://www.mitup.ru/$1 – куда перенаправляем. Где $1 – подстановка пришедших символов из (.*).

[R=301,L] – флаги. R – вызывает 301 редирект, L (last) – указывает на последнее правило и остановку процесса преобразования на этом месте. Подробнее про флаги.

Таким образом, мы перенаправляем пользователя на без www и сохраняем URL, на который он перешел.

3. С HTTP на HTTPS

Здесь есть несколько вариантов. Если один не сработал – пробуйте другой)

Пример №1:

RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

где,

  • RewriteCond %{HTTPS} off – проверка на отсутствие HTTPS протокола;

%{HTTPS} – это переменная сервера, которая содержит значение "on" или "off" в зависимости от того, был ли запрос к серверу выполнен через защищенное соединение HTTPS или нет.

off – это ключевое слово, которое указывает на значение переменной %{HTTPS} и означает, что запрос был выполнен без защищенного соединения HTTPS.

  • RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} – перенаправление с любого URL, на который попал пользователь с подстановкой протокола HTTPS в начале URL;

(.*) – регулярное выражение, которое обозначает любой символ. Это группа захвата, которая будет использована в дальнейшем.

https://%{HTTP_HOST}%{REQUEST_URI} – URL-адрес, на который будет происходить перенаправление. Он состоит из протокола ("https://"), имени хоста ("% {HTTP_HOST}") и пути запроса ("% {REQUEST_URI}"). Знак процента ("%") указывает, что это переменная сервера, которая будет заменена соответствующим значением.

Пример №2:

RewriteCond %{SERVER_PORT} !^443$
RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]

где:

  • RewriteCond %{SERVER_PORT} !^443$ – проверка на отсутствие 443 порта у сайта (443 порт отвечает за HTTPS протокол). Проверка идентична примеру выше, только сравнивается не протокол, а порт.

%{SERVER_PORT} – переменная сервера, которая содержит номер порта, на котором происходит текущий запрос.

!^443$ – регулярное выражение, которое проверяет, не равен ли текущий порт 443. Здесь ! – отрицание, ^ – начало строки, 443 - число, соответствующее порту HTTPS, а $ – конец строки. Если текущий порт не равен 443 (т.е, если запрос не выполняется через HTTPS), то условие считается истинным, и перезапись URL-адреса может быть выполнена.

  • RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} – была рассмотрена в примере выше.

Пример №3:

RewriteCond %{HTTPS} off
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

То же самое, но немного изменено, наподобие примера №1,

где:

  • RewriteCond %{HTTPS} off – проверка на отсутствие HTTPS протокола;

%{HTTPS} – это переменная, которая содержит значение "on" или "off" в зависимости от того, происходит ли соединение по защищенному протоколу HTTPS или нет.

off – это значение, с которым сравнивается переменная %{HTTPS} в данном случае. То есть, данная команда проверяет, равна ли переменная %{HTTPS} значению "off". Если это так, то условие считается истинным, и выполняется соответствующее действие (например, перенаправление на защищенный протокол).

  • RewriteCond %{HTTP:X-Forwarded-Proto} !https проверка на отсутствие в URL HTTPS протокола, информации о схеме исходного запроса клиента (будь то http или https-запрос);

%{HTTP:X-Forwarded-Proto} – переменная, которая используется для доступа к значению заголовка X-Forwarded-Proto в запросе. Значение этого заголовка определяет, был ли запрос отправлен по HTTPS или HTTP.

!https – условие проверки. В данном случае, оно означает, что условие будет выполнено, если значение переменной %{HTTP:X-Forwarded-Proto} не равно "https". То есть, если запрос был отправлен по HTTP, а не по HTTPS.

  • RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} – была рассмотрена выше.

4. Дубли со слешем

Пример (со страниц вида https://mitup.ru на https://mitup.ru/):

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

где:

  • RewriteCond %{REQUEST_URI} /+[^\.]+$ – проверяет, содержит ли текущий URL-адрес один или более слешей, за которыми не следует точка (которая может указывать на расширение файла);

%{REQUEST_URI}: Это переменная, содержащая запрошенный URL без домена.

/+ – означает, что перед точкой (.) может быть один или несколько символов слэша (/). Знак + является квантификатором, указывающим, что предыдущий символ должен встретиться один или более раз.

[^\.]+ – означает, что после последнего слэша не должно быть точки (.). Знак ^ означает отрицание, т.е. любой символ, кроме точки. Знак + также указывает на то, что предыдущий символ должен встретиться один или более раз.

$ – означает, что шаблон должен соответствовать концу строки (URI).

  • RewriteRule ^(.+[^/])$ %{REQUEST_URI}/ [R=301,L] – перенаправляет запросы на URL-адреса, которые не заканчиваются на слеш, на новый URL-адрес с добавлением слеша в конце.

^(.+[^/])$ – регулярное выражение, которое соответствует любому URI (Uniform Resource Identifier), заканчивающемуся не на слэш (/). Знак ^ обозначает начало строки, знак $ обозначает конец строки. Квантификатор + обозначает "один или более раз", а [^/] означает "любой символ, кроме слэша".

%{REQUEST_URI}/ – новый URI, на который будет произведено перенаправление. Он будет состоять из запрошенного URI и слэша (/) в конце.

  • [R=301,L] – флаги указывают на тип перенаправления и прерывание обработки правил перезаписи. R=301 означает "постоянное перенаправление" (301 Moved Permanently), что говорит браузеру и поисковым системам, что этот URL был окончательно перемещен на новый URL. L означает "последнее правило" (last), что говорит серверу прервать обработку правил перезаписи и выполнять перенаправление.

Пример (со страниц вида https://mitup.ru/ на https://mitup.ru)

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

где:

  • RewriteCond %{REQUEST_URI} !\? – проверяет, не содержит ли текущий URL-адрес знака вопроса;

%{REQUEST_URI} – переменная, содержащая запрошенный URI (Uniform Resource Identifier).

!\? – регулярное выражение, которое проверяет отсутствие знака вопроса (?) в URI. Символ ! означает отрицание, а знак вопроса (?) соответствует знаку вопроса в URL.

  • далее идут похожие директивы, которые проверяют URL на содержание других знаков;
  • RewriteRule ^(.*)\/$ /$1 [R=301,L] – выполняет перенаправление (редирект) для всех URL-адресов, которые заканчиваются на слеш "/", на соответствующий URL-адрес без слеша.

^(.*)\/$ – регулярное выражение, которое соответствует любому URI (Uniform Resource Identifier), заканчивающемуся на слэш (/). Знак ^ обозначает начало строки, а знак $ обозначает конец строки. Квантификатор * обозначает "любой символ, ноль или более раз", а / обозначает слэш (/).

/$1 – новый URI, на который будет произведено перенаправление. Он будет состоять из той же части URI, которая находится перед последним слэшем (/).

- [R=301,L] – был рассмотрен в примере выше.

5. Перенаправление с index.php в конце на без index.php

Пример:

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTP/
RewriteRule ^index\.php$ http://name.site/ [R=301,L]

где:

  • RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTP/ – проверяет, содержит ли строка запроса, отправленного клиентом (HTTP-запрос), текст "/index.php";

%{THE_REQUEST} – переменная сервера Apache, содержащая первую строку запроса HTTP от клиента, включая метод запроса HTTP, URI (Uniform Resource Identifier) и версию протокола HTTP.

^[A-Z]{3,9}\ /index\.php\ HTTP/ – регулярное выражение, которое соответствует строке запроса, содержащей имя файла "index.php". Знак ^ обозначает начало строки, а $ обозначает конец строки. [A-Z] обозначает любой символ в верхнем регистре от A до Z, а {3,9} обозначает повторение предыдущего символа от 3 до 9 раз. Слэш (/) и точка (.) экранированы обратным слэшем (), чтобы они были интерпретированы как обычные символы. HTTP/ обозначает окончание строки запроса.

  • RewriteRule ^index\.php$ http://name.site/ [R=301,L] – выполняет перенаправление (редирект) для всех запросов с index.php на страницу http://name.site/.

^index\.php$ – регулярное выражение, которое соответствует только URL, содержащему полное имя файла "index.php" в корневом каталоге сайта. Знак ^ обозначает начало строки, а $ обозначает конец строки. Точка (.) экранирована обратным слэшем (), чтобы она была интерпретирована как обычный символ.

http://name.site/ – новый URL, на который будет происходить перенаправление запроса.

[R=301,L] – был рассмотрен выше.

6. Перенаправление с верхнего регистра в url на нижний

Данный способ содержит большой набор директив, но не требует доступа к настройкам Apache. Официальный источник: Redirect htaccess for Uppercase to Lowercase

RewriteEngine On
RewriteBase /
# If there are caps, set HASCAPS to true and skip next rule
RewriteRule [A-Z] - [E=HASCAPS:TRUE,S=1]
# Skip this entire section if no uppercase letters in requested URL
RewriteRule ![A-Z] - [S=28]
# Replace single occurance of CAP with cap, then process next Rule.
RewriteRule ^([^A]*)A(.*)$ $1a$2
RewriteRule ^([^B]*)B(.*)$ $1b$2
RewriteRule ^([^C]*)C(.*)$ $1c$2
RewriteRule ^([^D]*)D(.*)$ $1d$2
RewriteRule ^([^E]*)E(.*)$ $1e$2
RewriteRule ^([^F]*)F(.*)$ $1f$2
RewriteRule ^([^G]*)G(.*)$ $1g$2
RewriteRule ^([^H]*)H(.*)$ $1h$2
RewriteRule ^([^I]*)I(.*)$ $1i$2
RewriteRule ^([^J]*)J(.*)$ $1j$2
RewriteRule ^([^K]*)K(.*)$ $1k$2
RewriteRule ^([^L]*)L(.*)$ $1l$2
RewriteRule ^([^M]*)M(.*)$ $1m$2
RewriteRule ^([^N]*)N(.*)$ $1n$2
RewriteRule ^([^O]*)O(.*)$ $1o$2
RewriteRule ^([^P]*)P(.*)$ $1p$2
RewriteRule ^([^Q]*)Q(.*)$ $1q$2
RewriteRule ^([^R]*)R(.*)$ $1r$2
RewriteRule ^([^S]*)S(.*)$ $1s$2
RewriteRule ^([^T]*)T(.*)$ $1t$2
RewriteRule ^([^U]*)U(.*)$ $1u$2
RewriteRule ^([^V]*)V(.*)$ $1v$2
RewriteRule ^([^W]*)W(.*)$ $1w$2
RewriteRule ^([^X]*)X(.*)$ $1x$2
RewriteRule ^([^Y]*)Y(.*)$ $1y$2
RewriteRule ^([^Z]*)Z(.*)$ $1z$2
# If there are any uppercase letters, restart at very first RewriteRule in file.
RewriteRule [A-Z] - [N]
RewriteCond %{ENV:HASCAPS} TRUE
RewriteRule ^/?(.*) /$1 [R=301,L]

где:

  • RewriteEngine On – включает модуль "mod_rewrite";
  • RewriteBase / – указывает на корневую директорию сайта, относительно которой будут применяться все правила переписывания URL-адресов в файле конфигурации;
  • # If there are caps, set HASCAPS to true and skip next rule – комментарий, указывает, что если в тексте содержатся заглавные буквы, то переменная HASCAPS будет установлена в значение true и следующее правило будет пропущено;
  • RewriteRule [A-Z] - [E=HASCAPS:TRUE,S=1] – выполняет проверку наличия заглавных букв в URL-адресе и устанавливает переменную HASCAPS равной "TRUE", если в URL-адресе присутствуют заглавные буквы;

[A-Z] – регулярное выражение, которое соответствует любой заглавной букве в URL.

- – символ тире, который указывает, что нет замены для URL.

[E=HASCAPS:TRUE] – флаг перезаписи, который устанавливает переменную окружения "HASCAPS" в значение "TRUE".

,S=1 – флаг перезаписи, который указывает модулю mod_rewrite, что это первое правило перезаписи в списке, и что выполнение правил перезаписи должно продолжаться сразу после этого правила (то есть, следующие правила не должны быть выполнены, если данное правило сработало).

  • # Skip this entire section if no uppercase letters in requested URL – комментарий указывает на то, что последующий блок правил перезаписи (или другой код), будет пропущен, если запрашиваемый URL-адрес не содержит заглавных букв (uppercase letters);
  • RewriteRule ![A-Z] - [S=28] – проверяет, содержит ли URL-адрес символы в верхнем регистре, и, если нет, она пропускает следующие 28 правил;

![A-Z] – регулярное выражение, которое соответствует любому символу в URL, за исключением заглавных букв.

- – символ тире, который указывает, что нет замены для URL.

[S=28] – флаг перезаписи, который указывает модулю mod_rewrite пропустить следующие 28 правил перезаписи.

  • # Replace single occurance of CAP with cap, then process next Rule – комментарий описывает правило RewriteRule, которое выполняет замену первого вхождения заглавной буквы "CAP" на строчную букву "cap", а затем переходит к следующему правилу;
  • RewriteRule ^([^A]*)A(.*)$ $1a$2 – заменяет заглавную букву "A" на строчную букву "a";

^ - символ начала строки.

([^A]*) – регулярное выражение, которое соответствует любому символу, за исключением заглавной буквы "A", 0 или более раз.

A – символ заглавной буквы "A".

(.*) – регулярное выражение, которое соответствует любому символу 0 или более раз.

$1a$2: заменяет URL на строку, которая состоит из:

- $1: содержимого первой группы, т.е. всех символов перед первым вхождением заглавной буквы "A".

- a: символа строчной буквы "a".

- $2: содержимого второй группы, т.е. всех символов после первого вхождения заглавной буквы "A".

  • следующие правила однотипны и направлены на замену всех заглавных букв на строчные;
  • # If there are any uppercase letters, restart at very first RewriteRule in file – комментарий описывает действие, которое нужно выполнить, если URL-адрес содержит хотя бы одну прописную (большую) букву;
  • RewriteRule [A-Z] – [N] – если в URL-адресе содержатся заглавные буквы, Apache перенаправит запрос на ту же страницу, но без заглавных букв;

[A-Z] – это регулярное выражение, которое соответствует любой заглавной букве в URL. Оно указывает на шаблон, который должен быть найден в URL.

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

[N] – это флаг перезаписи, который указывает модулю mod_rewrite продолжить обработку URL с того же места, где была обнаружена заглавная буква. Это означает, что правило перезаписи должно быть выполнено еще раз, начиная с этого места, в то время как обычно правило перезаписи выполняется один раз.

  • RewriteCond %{ENV:HASCAPS} TRUE – правило проверяет переменную среды "HASCAPS" на наличие значения "TRUE";

%{ENV:HASCAPS} – специальная переменная, которая обозначает значение переменной окружения "HASCAPS". Она начинается с %, за которым следует название переменной окружения в формате ENV:HASCAPS.

TRUE – значение, с которым переменная окружения "HASCAPS" сравнивается. Если переменная окружения "HASCAPS" имеет значение "TRUE", то условие считается выполненным.

  • RewriteRule ^/?(.*) /$1 [R=301,L] – перенаправляет все запросы, включая пустые, на URL-адрес без начального слеша.

Pattern: ^/?

- ^ – Этот символ означает, что URL должен начинаться с соответствующей строки.

- /? – регулярное выражение соответствует нулю или одному слешу в начале URL.

Substitution: /$1

- /$1 – означает, что весь URL запроса, начиная со второго символа, будет заменен на $1. Переменная $1 представляет первое вхождение шаблона в Pattern.

Flags: [R=301,L]

- R=301 – флаг указывает на перенаправление с кодом ответа 301, который означает, что запрашиваемая страница была окончательно перенесена в другое местоположение.

- L – флаг означает, что выполнение дальнейших правил должно быть прекращено, если это правило перезаписи сработало.

7. htaccess редирект на другой домен

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

Пример настройки:

RewriteEngine On
RewriteRule ^(.*)$ http://www.mitup.ru/$1 [R=301,L]

где:

RewriteRule ^(.*)$ http://www.mitup.ru/$1 [R=301,L] – выполняет перенаправление всех запросов на новый адрес http://www.mitup.ru/ с кодом ответа 301.

  • ^(.*)$ – это регулярное выражение, которое соответствует любому URL, включая все символы и путь к файлу.
  • http://www.mitup.ru/$1 – URL-адрес, на который происходит перенаправление. $1 – это backreference, который содержит всю строку, соответствующую регулярному выражению в части ^(.*)$, и вставляет ее в конец URL-адреса назначения.
  • [R=301,L] – рассмотрен выше.

8. Для страниц с 404 ответом сервера на главную

Такой htaccess редирект с одной страницы с 404 ошибкой актуален для интернет-магазинов, когда товары распроданы, но терять пользователей не хочется.

Пример

ErrorDocument 404 http://www.site.com/301.html

где:

  • ErrorDocument 404 http://www.site.com/301.html – определяет адрес URL-страницы, которая будет отображаться вместо стандартной страницы ошибки 404 (Not Found) на сайте, когда запрашиваемый ресурс не может быть найден на сервере.
  • ErrorDocument – ключевое слово, которое указывает, что это директива настройки страницы ошибки.
  • 404 – код ошибки HTTP, которая настраивается в данном случае. Код 404 означает, что запрошенная страница не была найдена на сервере.
  • http://www.site.com/301.html – URL-адрес страницы ошибки, которая будет отображаться пользователю, если произойдет ошибка 404.

9. Генерация правил редиректов

Чтобы не допустить ошибки в скрипте, можно воспользоваться сервисами для его автоматического формирования. Примеры сервисов: .htaccess Generator, 301 Redirect Code Generator, Winginx (возможно перевести код для веб-сервера Nginx). Результаты, полученные при помощи сервисов, также необходимо внимательно проверять.

Заключение

Существует множество способов настроить 301 редирект. Через файл настройки .htaccess это сделать просто и эффективно, но в то же время опасно, так как ошибка может повлиять на весь каталог. Для работы с любыми настройками конфигурации существует свод правил, которых необходимо придерживаться, и также следует тщательно проверять настройки.

Читайте также:

Озон Селлер с нуля: запуск с минимумом затрат и рост продаж на живом примере
Mitup24 февраля 2023
Google Indexing API – быстрая индексация в Google
Mitup13 февраля 2023
Как поднять поисковый трафик более чем в 10 раз в высоко-конкурентной нише и с несговорчивым заказчиком
Mitup6 февраля 2023