Кэш браузера в .htaccess: mod_expires и Cache-Control
Строки mod_expires в .htaccess разрешают браузеру хранить картинки, стили и скрипты у себя: пока срок не истёк, он берёт их из своего кэша и не скачивает заново, и сайт открывается быстрее. Apache добавляет к таким файлам заголовки Cache-Control и Expires со сроком хранения.
Содержание 12
Что сделать прямо сейчас
- Перед правкой сохраните копию файла .htaccess к себе на компьютер: если что-то пойдёт не так, её можно будет вернуть.
- Проверьте, нет ли кэширования уже, — как проверить. Если строки Cache-Control и Expires со сроком в ответе есть, ничего добавлять не нужно.
- Добавьте в .htaccess корневой папки блок из раздела ниже. Сохраните файл и сразу откройте сайт. Если появилась ошибка 500, уберите добавленные строки — сайт заработает как раньше.
- Проверьте снова: в ответе должно появиться max-age=2592000.
Блок для картинок, стилей и скриптов
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/webp "access plus 1 month"
ExpiresByType image/svg+xml "access plus 1 month"
ExpiresByType text/css "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
</IfModule>Строка ExpiresActive On включает модуль, а каждая строка ExpiresByType задаёт срок для своего типа файлов. Месяц mod_expires считает за 30 дней, поэтому в ответе будет max-age=2592000 — столько секунд в 30 днях.
Блок IfModule защищает от ошибки 500: если модуль не загружен, Apache пропустит строки внутри. Но тогда не будет и кэширования — поэтому после правки проверьте заголовки через curl.
Страницы сайта (text/html) в список не добавляйте: иначе посетители могут не увидеть изменений на страницах, пока не истечёт срок.
Как узнать тип файла
Тип в строке ExpiresByType должен совпасть с типом, который сервер называет в заголовке Content-Type. Узнать его можно так:
curl -sI https://example.com/css/style.css | grep -i content-typeЕсли curl показал тип с добавкой, например text/css; charset=utf-8, в строку ExpiresByType пишите только часть до точки с запятой — text/css. Скрипты сервер может назвать text/javascript или application/javascript, поэтому в блоке обе строки. Для шрифтов и других файлов добавьте строку с тем типом, который показал curl.
В командной строке Windows команды grep нет: наберите команду без части после вертикальной черты и найдите строку Content-Type в ответе.
Что значат сроки
Срок пишут в кавычках: от какого момента считать, слово plus, число и единицу времени.
access— от запроса посетителя. Подходит для картинок, стилей и скриптов.modification— от последнего изменения файла на сервере. Если ответ берётся не из файла на диске, заголовка Expires не будет.- Единицы — years, months, weeks, days, hours, minutes и seconds. Их можно сочетать:
"access plus 1 week 3 days".
Cache-Control через Header
Тот же срок можно задать строкой Header из модуля mod_headers. Выберите один способ: если оставить оба, в ответе может оказаться два разных срока.
<IfModule mod_headers.c>
<FilesMatch "\.(jpe?g|png|webp|svg|css|js)$">
Header set Cache-Control "max-age=2592000"
</FilesMatch>
</IfModule>Шаблон в FilesMatch перечисляет окончания имён файлов через вертикальную черту, а jpe?g означает и jpg, и jpeg. Число 2592000 — 30 дней в секундах. Заголовка Expires этот способ не добавляет.
Что делать после обновления файлов
Браузер, который уже сохранил старый файл стилей, может брать его из кэша до конца срока. Чтобы посетители сразу получили новый, добавьте к адресу файла в коде страниц метку версии:
<link rel="stylesheet" href="/css/style.css?v=2">После следующей правки поменяйте метку на v=3 — для браузера это новый адрес, и он скачает файл заново. Так же это делается для nginx.
Как проверить
В терминале компьютера (как открыть терминал, про curl) узнайте адрес файла стилей вашего сайта — он указан в коде главной страницы. На Mac и Linux его покажет команда — вместо example.com впишите свой сайт:
curl -sL https://example.com/ | grep -o "href=[^ >]*\.css[^ >]*"Команда выведет строки вида href="…": адрес — то, что в кавычках. В Windows откройте главную страницу сайта в Chrome и нажмите Ctrl+U — откроется код страницы; найдите в нём .css через Ctrl+F.
Если адрес начинается с косой черты, например /css/style.css, допишите впереди https:// и имя сайта. Если в адресе есть знак вопроса, например style.css?ver=6.4, отбросьте его вместе со всем, что после него. Теперь запросите заголовки файла:
curl -sI https://example.com/css/style.css | grep -i 'cache-control\|expires'В ответе должна быть строка Cache-Control со словами max-age=2592000 и строка Expires с датой на 30 дней вперёд. curl может показать имена заголовков маленькими буквами — это то же самое. Если строк нет, смотрите разбор ниже.
В командной строке Windows команды grep нет: наберите команду без части после вертикальной черты и найдите строки Cache-Control и Expires в ответе.
На хостинге
На хостинге вставьте блок в .htaccess корневой папки сайта через файловый менеджер в панели — где лежит файл.
В справке Beget о подключении SSL, в части про переадресацию на HTTPS, сказано, что правила из .htaccess работают только для динамических данных. Если после правки у картинок и стилей нет заголовков Cache-Control и Expires, спросите поддержку хостинга, как включить кэширование для таких файлов.
На своём VPS
Модули expires и headers не включаются при установке Apache в Ubuntu — включите нужный командой ниже. Команды вводятся на сервере: подключитесь к нему по SSH (как подключиться) и набирайте их в том же окне.
sudo a2enmod expiresЕсли пользуетесь строкой Header, включите и его модуль: sudo a2enmod headers. Затем проверьте настройки: sudo apache2ctl configtest — в конце ответа должно быть Syntax OK — и примените их: sudo systemctl restart apache2.
Строкам Expires в .htaccess нужна группа Indexes, строке Header — FileInfo. Проще всего разрешить всё: AllowOverride All — как разрешить .htaccess.
Если сайт работает на nginx, кэш настраивается строкой expires — кэширование в nginx.
Ошибки и как их исправить
| Что видите | Что делать |
|---|---|
| в ответе нет Cache-Control и Expires | модуль не включён — блок IfModule пропускается без ошибки: на VPS включите его командой sudo a2enmod expires. Или тип файла не совпал — сверьте тип. На хостинге спросите поддержку — см. выше |
| ошибка 500 после сохранения | опечатка, незакрытый блок или на VPS не разрешена нужная группа — разбор |
| посетители видят старые стили | добавьте к адресу метку версии — как |
| срок в Expires не тот, что в .htaccess | Expires уже поставил скрипт сайта, например PHP, — mod_expires такие ответы не меняет |
| с modification заголовка Expires нет | ответ берётся не из файла на диске — используйте отсчёт от access |
Источники
- Документация Apache: mod_expires — строки ExpiresActive и ExpiresByType, отсчёт от access или modification, единицы от years до seconds; модуль ставит Expires и max-age в Cache-Control и не трогает ответы, где Expires уже есть; без файла на диске отсчёт от modification не работает; в .htaccess нужна группа Indexes.
- Документация Apache: Header — строка Header set задаёт заголовок ответа; в .htaccess нужна группа FileInfo.
- Документация Apache: IfModule — строки внутри блока выполняются, только если модуль загружен, иначе Apache их пропускает; блок можно писать в .htaccess.
- Документация Apache: FilesMatch — блоки Files и FilesMatch можно писать в .htaccess; в FilesMatch имя файла задают регулярным выражением.
- Исходный код Apache 2.4.58: mod_expires.c — месяц — 30 дней, неделя — 7, год — 365; в Cache-Control уходит max-age в секундах; тип сверяется без добавки после точки с запятой.
- Сценарий установки из пакета apache2 в Ubuntu 24.04 — модули, которые включаются при установке; rewrite, expires и headers в этом списке нет.
- Beget: SSL-сертификат на сайт — в части про переадресацию на HTTPS: правила из .htaccess работают только для динамических данных.
- Справка Chrome: быстрые клавиши — Ctrl+U показывает HTML-код страницы, Ctrl+F ищет текст.
Сверено 15 октября 2026 года.
Что почитать дальше
- Кэширование в nginxто же для сайта на nginx.
- Сжатие gzip в .htaccessвторой способ ускорить сайт.
- .htaccess не работаетошибка 500 и строки, которые не действуют.
- Файл .htaccessчто это, как создать и не сломать сайт.