К основному содержимому

.htaccess: правила редиректов и оптимизации

Хостинг и cPanel · 26.02.2025 · 4 мин чтения
Иллюстрация к статье «.htaccess: правила редиректов и оптимизации»

.htaccess — конфигурационный файл Apache, который применяет правила к папке, в которой лежит, и ко всем вложенным. На shared-хостинге это единственный способ управлять сервером без доступа к главному конфигу — но каждая ошибка в синтаксисе кладёт весь сайт с ошибкой 500, поэтому редактировать файл нужно аккуратно и с резервной копией под рукой.

Принудительный HTTPS

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

Условие %{HTTPS} off срабатывает только для запросов без TLS, поэтому правило не зацикливается на уже защищённых страницах.

Флаги правил rewrite: что означают

ФлагЗначение
LLast — прекратить обработку остальных правил после этого
R=301Постоянный редирект (302 без числа — временный)
NCNo Case — регистр в условии не учитывается
QSAQuery String Append — сохранить GET-параметры при редиректе

Без QSA ссылка вида example.com/page?utm_source=ads после редиректа потеряет параметр utm_source — это разрушает аналитику рекламных кампаний, поэтому для правил с параметрами флаг обязателен.

Редирект www → без www

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

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

Частая ошибка: 500 Internal Server Error

После правки .htaccess сайт вдруг показывает ошибку 500. В error_log домена находится причина:

[Wed Sep 24 10:12:03 2026] [core:alert] [pid 8842] /home/user/public_html/.htaccess:
Invalid command 'RewriteEngin', perhaps misspelled or defined by a module
not included in the server configuration

Это опечатка в названии директивы (RewriteEngin вместо RewriteEngine) — Apache не может её распознать и останавливает обработку всего файла. Второй частый вариант той же ошибки — модуль mod_rewrite не подключён на сервере вовсе, тогда сообщение будет «not included in the server configuration» без опечатки в тексте директивы.

Кэширование в браузере

<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresByType image/jpeg "access plus 1 year"
  ExpiresByType image/png  "access plus 1 year"
  ExpiresByType image/webp "access plus 1 year"
  ExpiresByType text/css   "access plus 1 month"
  ExpiresByType application/javascript "access plus 1 month"
</IfModule>
Тип файлаРекомендуемый срокПочему
Изображения1 годМеняются редко, версионируются через имя файла
CSS / JS1 месяцОбновляются чаще, риск подать устаревшую версию
HTMLБез кэша или минутыКонтент страницы должен обновляться сразу
Шрифты1 годПрактически никогда не меняются

GZIP сжатие

<IfModule mod_deflate.c>
  AddOutputFilterByType DEFLATE text/html text/css
  AddOutputFilterByType DEFLATE application/javascript application/json
</IfModule>

GZIP через mod_deflate уменьшает текстовые ответы на 60–80%, но не сжимает уже сжатые форматы — добавлять в список image/jpeg или video/mp4 бессмысленно, сервер только потратит CPU без выигрыша в размере.

Защита директории

# Запрет доступа к папке (Apache 2.2)
<Files *>
  Order Deny,Allow
  Deny from all
</Files>

# Защита wp-config.php
<Files wp-config.php>
  Order Allow,Deny
  Deny from all
</Files>
# Тот же запрет для Apache 2.4+
<Files wp-config.php>
  Require all denied
</Files>

Директивы Order/Deny относятся к mod_access_compat из Apache 2.2 — на новых серверах с Apache 2.4 работает синтаксис Require all denied, и лучше использовать именно его, если хостинг это поддерживает.

Когда правила в .htaccess не сработают

  • В главном конфиге сервера стоит AllowOverride None для директории — тогда Apache вообще не читает .htaccess, и никакие правки эффекта не дадут
  • Модуль mod_rewrite или mod_expires отключён администратором — обратитесь в поддержку хостинга за подтверждением
  • Сайт работает на Nginx, а не на Apache — .htaccess Nginx не читает вообще, правила нужно переносить в конфиг server{}
  • Провайдер использует LiteSpeed без модуля совместимости с Apache-директивами — часть редких правил (например, mod_security через .htaccess) там не поддерживается

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

curl -I http://example.com/
# Ожидаем: HTTP/1.1 301 Moved Permanently
# Location: https://example.com/

Заголовок Location должен указывать на финальный HTTPS-адрес без www (или с www — в зависимости от выбранного канонического варианта), а код ответа — именно 301, а не 302, иначе поисковики не передадут вес страницы на новый адрес. Подробнее про типы SSL и настройку HTTPS — в статье редирект с HTTP на HTTPS, а про запрет чужих ссылок на картинки — в статье Hotlink Protection.

Статья помогла?
← Назад в базу знаний Задать вопрос поддержке