Примеры ниже предназначены для Apache 2.4 с mod_rewrite и разрешёнными правилами в .htaccess. Подставьте свой домен вместо example.com. Это отдельные варианты: противоположные правила для www, HTTPS и слеша нельзя включать одновременно. За обратным прокси способ определения HTTPS зависит от настроек сервера.
Основной адрес при запуске
Вариант с HTTPS без www. Обращение к index.php или index.html перенаправляется только тогда, когда имя файла было в исходном запросе клиента: это не ломает внутреннюю маршрутизацию CMS.
RewriteEngine On
# Запрещаем прямой доступ к служебным файлам примера.
RewriteRule ^(?:\.htaccess|template\.php)$ - [F,L]
# index.php и index.html в корне — на главную.
RewriteCond %{THE_REQUEST} \s/+index\.(?:php|html)(?:[?\s]) [NC]
RewriteRule ^index\.(?:php|html)$ https://example.com/ [R=301,L]
# Совмещаем выбор домена и HTTPS, чтобы избежать цепочки.
RewriteCond %{HTTPS} !=on [OR]
RewriteCond %{HTTP_HOST} !^example\.com$ [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [R=301,L]
# Локальный обработчик: отсутствующая страница должна сохранить статус 404.
ErrorDocument 404 /404.php
Внешний URL в ErrorDocument вызывает перенаправление и меняет исходный статус ошибки. Если обработку выполняет PHP, обработчик также должен вернуть 404. Проверьте это по HTTP-ответу; наличие надписи «404» на странице недостаточно.
С домена без www на www
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,L]
С www на домен без www
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [R=301,L]
С HTTP на HTTPS
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://example.com%{REQUEST_URI} [R=301,L]
Обратный вариант из исходной подборки — только для намеренного перехода на HTTP. Он отключает защищённый адрес и обычно не нужен публичному сайту.
RewriteCond %{HTTPS} =on
RewriteRule ^ http://example.com%{REQUEST_URI} [R=301,L]
Страницы, каталоги и параметры
С одной статической страницы на другую
RewriteRule ^was\.php$ https://example.com/new.php [R=301,L]
Альтернативный вариант с mod_alias:
Redirect 301 /was.php https://example.com/new.php
Redirect сопоставляет начало пути и может дописать его остаток. Для точного совпадения страницы используйте показанное правило mod_rewrite либо RedirectMatch с якорями. Смешивание mod_alias и mod_rewrite требует отдельной проверки порядка обработки.
С известными GET-параметрами
RewriteCond %{QUERY_STRING} ^IBLOCK_ID=1&SECTION_ID=111$ [NC]
RewriteRule ^dir/index\.php$ https://example.com/new/sef/ [R=301,L,QSD]
Этот пример ожидает ровно два параметра в указанном порядке. Если приложение допускает иной порядок или дополнительные параметры, обработайте их явно; не считайте такой шаблон универсальным разбором query string.
Когда значение SECTION_ID заранее неизвестно
RewriteCond %{QUERY_STRING} ^IBLOCK_ID=1&SECTION_ID=[^&]+$ [NC]
RewriteRule ^dir/index\.php$ https://example.com/new/sef/ [R=301,L,QSD]
QSD удаляет строку запроса. В этом варианте значение SECTION_ID намеренно не переносится. Если каждому разделу нужен свой новый адрес, потребуется таблица соответствий. Не удаляйте параметры, от которых зависит содержание, авторизация или оформление заказа.
С одной категории на другую
RewriteRule ^dir/$ https://example.com/new-dir/ [R=301,L]
Перенос каталога с сохранением остатка пути
RewriteRule ^dir/(.*)$ https://example.com/dir-new/$1 [R=301,L]
Добавление слеша
Пример только для адресов без расширения, которые не являются существующими файлами или каталогами:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^.]*[^./])$ https://example.com/$1/ [R=301,L]
Путь с точкой этот шаблон намеренно не обрабатывает. Согласуйте правило с маршрутизацией сайта.
Удаление слеша
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ https://example.com/$1 [R=301,L]
С файлов каталога на один заданный файл
RewriteRule ^dir(?:/.*)?$ https://example.com/new-file.php [R=301,L]
Исключение одного файла из общего правила
RewriteRule ^dir/no-file\.html$ https://example.com/no-file-new.html [R=301,L]
RewriteRule ^dir(?:/.*)?$ https://example.com/all.php [R=301,L]
Для одинакового имени файла в разных каталогах
RewriteRule ^(?:[^/]+/)+unique-file\.html$ https://example.com/unique-file.html [R=301,L]
Корневой unique-file.html исключён, поэтому правило не перенаправляет страницу на саму себя.
Удаление всех GET-параметров
RewriteCond %{QUERY_STRING} !^$
RewriteRule ^ https://example.com%{REQUEST_URI} [R=301,L,QSD]
Проверка непустой строки запроса предотвращает повторный редирект уже очищенного URL. Используйте правило только там, где параметры не меняют содержимое.
Между доменами и поддоменами
Одна страница на другом домене
RewriteRule ^kastraciya/$ https://new.example.com/uslugi/kastracija-sobaki-na-domu.html [R=301,L]
Только главная на главную другого домена
RewriteRule ^$ https://new.example.com/ [R=301,L]
Якорь $ нужен: шаблон ^ без него совпадёт со всеми путями.
Все страницы на соответствующие страницы нового домена
RewriteCond %{HTTP_HOST} ^(?:www\.)?old\.example\.com$ [NC]
RewriteRule ^ https://new.example.com%{REQUEST_URI} [R=301,L]
Все страницы на главную другого домена
RewriteCond %{HTTP_HOST} ^(?:www\.)?old\.example\.com$ [NC]
RewriteRule ^ https://new.example.com/ [R=301,L]
Это технически возможно, но не заменяет карту переезда. Массовое перенаправление разных материалов на нерелевантную главную может обрабатываться поиском как soft 404. Для переноса содержимого выбирайте соответствующие страницы.
Все поддомены на основной адрес
RewriteCond %{HTTP_HOST} ^[a-z0-9_-]+\.example\.com$ [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [R=301,L]
Только заданный поддомен
RewriteCond %{HTTP_HOST} ^test\.example\.com$ [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [R=301,L]
Папка одного домена в папку другого
RewriteCond %{HTTP_HOST} ^old\.example\.com$ [NC]
RewriteRule ^dir/(.*)$ https://new.example.com/dir-new/$1 [R=301,L]
Перенос с исключением папки bitrix
RewriteRule ^bitrix(?:/|$) - [L]
RewriteRule ^ https://new.example.com/new/ [R=301,L]
Это исключает всю папку bitrix из следующего правила, включая административный раздел. Оно не заменяет контроль доступа и правила самой CMS. В данном примере остальные страницы ведут на один URL; для обычного переезда предпочтительно соответствие страниц.
Порядок правил и проверка
- Размещайте точные соответствия и исключения перед общими шаблонами. Результат зависит также от флагов, контекста и внутренних повторных проходов.
- Направляйте исходный адрес сразу на конечный, объединяя смену домена, протокола и пути там, где это возможно.
- RewriteCond относится к следующему RewriteRule. Условия по умолчанию объединяются как AND; [OR] меняет связь с последующим условием.
- RewriteRule в .htaccess корня видит путь без начального слеша. Убедитесь, что mod_rewrite включён и AllowOverride разрешает эти директивы.
- Options +FollowSymLinks из старых примеров не следует без проверки добавлять на любой хостинг: разрешённые Options задаёт администратор сервера.
- Для кириллического домена используйте его ASCII-представление IDNA. Кодировка пути — отдельный вопрос; не заменяйте всю кириллицу в URL одним способом.
- Браузер может запомнить постоянный редирект. Проверяйте HTTP-ответ без такого кэша, например curl, а не только открытием страницы. Bertal и Mainspy были внешними сервисами проверки в исходной подборке; их текущая работа здесь не подтверждена.
curl -I https://example.com/old-page/
curl -I -L https://example.com/old-page/
Проверьте Location, число переходов, код конечной страницы и отсутствие петель. Примеры конфигурации нужно проверить на тестовом сервере; это не отчёт об их запуске на вашем хостинге.
Регулярные выражения и флаги
| Обозначение | Значение |
|---|---|
. | Один произвольный символ; буквальную точку экранируют как \.. |
[abc] | Один символ из набора a, b, c. |
[^abc] | Один символ вне указанного набора. |
* | Предыдущий элемент повторяется ноль или более раз. |
[abc]*, [^abc]* | Последовательность символов из набора или вне него. |
.* | Последовательность произвольных символов, включая пустую. |
"[^"]*" | Фрагмент в двойных кавычках без внутренних двойных кавычек. |
^, $ | Начало и конец строки. |
\w, \d, \D | Класс символов слова, цифры, нецифровые символы; точный состав зависит от режима регулярного выражения. |
[0-9] | Цифра от 0 до 9. |
[a-z], [A-Z], [a-zA-Z] | Латинские буквы заданного регистра или обоих. Старое [a-Z] не является корректной заменой [a-zA-Z]. |
! перед RewriteCond | Отрицание условия. |
() | Группировка; захваченные группы RewriteRule доступны как $1, а RewriteCond — как %1. |
\ | Экранирование специального символа. |
?, + | Ноль или одно повторение; одно или более повторений. Универсального предела 65536 здесь нет. |
[NC] | Сопоставление без учёта регистра. |
[R], [R=301] | Внешнее перенаправление; R без кода по умолчанию означает 302. |
[L] | Остановка текущего прохода правил, а не всех возможных внутренних проходов. |
[END] | Завершение обработки per-directory rewrite в Apache 2.4. |
[QSD], [QSA] | Удаление исходной строки запроса; добавление её к новой строке запроса. |
Документация: флаги mod_rewrite, ErrorDocument, переезд сайта в Google.