Гид по технологиям

nginx: Expires и Cache-Control для статических файлов

• 6 min read • DevOps • Обновлено 26 Nov 2025
nginx: Expires и Cache-Control для статических файлов
nginx: Expires и Cache-Control для статических файлов

Введение

Это руководство объясняет, как в nginx задать заголовок Expires и директиву max-age заголовка Cache-Control для статических файлов (изображения, CSS, JavaScript). Правильная настройка позволяет браузерам посетителей кэшировать ресурсы на стороне клиента, экономя пропускную способность и ускоряя повторные посещения сайта.

Важно: кэширование имеет смысл только для неизменяемых или версионированных ресурсов. Если файл будет изменён без смены имени, браузеры не обновят его автоматически.

Предварительная заметка

Предполагается, что у вас уже есть рабочая конфигурация nginx (LEMP или другая), и вы умеете перезагружать сервис после правок. Если нет — сначала настройте nginx и PHP/MariaDB по подходящему руководству для вашей ОС.

Настройка nginx

Директива expires позволяет задавать Expires и управлять Cache-Control. Её можно поместить внутрь блоков http {}, server {}, location {} или в if внутри location {}. Чаще всего её используют в location для статических файлов:

location ~*  \.(jpg|jpeg|png|gif|ico|css|js)$ {  
   expires 365d;  
}

В этом примере всем файлам с расширениями .jpg, .jpeg, .png, .gif, .ico, .css и .js добавляется заголовок Expires через 365 дней от времени доступа браузера. Убедитесь, что такой блок действительно обслуживает только статические ресурсы.

Для применения изменений перезагрузите nginx:

/etc/init.d/nginx reload

Что умеет expires

  • off — не изменять заголовки Expires и Cache-Control.
  • epoch — установить Expires в 1 января 1970 00:00:01 GMT.
  • max — установить Expires на 31 декабря 2037 23:59:59 GMT и Cache-Control: max-age равный примерно 10 годам.
  • Время без префикса @ — относительное к моменту доступа браузера. Можно указать отрицательное значение, чтобы задать no-cache: например, expires -1s; или expires 0;
  • Время с префиксом @ — абсолютное время суток в форме Hh или Hh:Mm (например, expires @15:34;).

Доступные единицы времени:

  • ms — миллисекунды
  • s — секунды
  • m — минуты
  • h — часы
  • d — дни
  • w — недели
  • M — месяцы (30 дней)
  • y — годы (365 дней)

Примеры: 1h30m — 1 час 30 минут, 1y6M — 1 год и 6 месяцев.

expire на основе даты изменения файла

Если ресурс хранится как реальный файл на диске, можно основать заголовок на дате модификации файла:

expires modified 10d;

Это удобно для файлов, которые обновляются редко, но при этом хотят задать срок жизни относительно времени изменения.

Важно: директива modified работает только для реальных файлов, а не для виртуальных ответов, генерируемых приложениями.

Практические рекомендации и лучшие практики

  • Всегда версионируйте изменяемые статические файлы: app.js → app-1.1.js или app.v202511.js. Это простая и надёжная стратегия принуждения браузеров скачать новую версию.
  • Устанавливайте короткий срок жизни для динамических и персонализированных ресурсов.
  • Никогда не кэшируйте чувствительные или приватные данные (страницы профиля, ответы, содержащие PII) — используйте заголовки Cache-Control: no-store, no-cache.
  • Сочетайте long-term кэширование статических ресурсов с контролем версии — это оптимальный компромисс производительности и безопасности.

Примеры конфигураций (шаблоны)

Шаблон для общих статических ресурсов:

location ~* \.(?:css|js|jpg|jpeg|png|gif|ico|svg)$ {
    expires 30d;
    add_header Cache-Control "public, max-age=2592000";
}

Шаблон для неизменяемых ресурсов с версией в имени (долгий кэш):

location ~* \.(?:css|js|jpg|jpeg|png|gif|ico|svg)$ {
    expires 365d;
    add_header Cache-Control "public, max-age=31536000, immutable";
}

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

Тестирование

Проверьте заголовки через инструменты разработчика браузера (Network) или с помощью curl:

curl -I https://example.com/path/to/image.png

В ответе вы должны увидеть строки типа:

  • Expires: Wed, 13 Nov 2026 12:00:00 GMT
  • Cache-Control: max-age=31536000

Пример скриншота заголовков в Firefox:

Снимок экрана DevTools с заголовками Expires и Cache-Control для статического файла

Когда это не работает (контрпримеры)

  • Файл отдаётся динамическим обработчиком (процессор, который формирует ответ на лету) — expires modified не сработает.
  • CDN поверх вашего сервера может перезаписать или игнорировать заголовки. Согласуйте настройки с CDN или укажите нужные правила там.
  • Неправильный location-блок или порядок правил в конфигурации nginx может приводить к тому, что правило не применяется — используйте nginx -T для отладки.
  • Если вы забыли версионировать файл, браузеры продолжат использовать старую версию до истечения срока кэша.

Альтернативные подходы

  • Управление кэшированием на уровне CDN — возможно, более гибкое и масштабируемое решение.
  • Добавление контрольных сумм (hash) в имена файлов при сборке ассетов (webpack, gulp) — автоматическая версия при каждом сборке.
  • Использование Service Workers для продвинутого кэширования на стороне клиента (PWA-подход).

Роли и чек-листы по внедрению

DevOps:

  • Добавить правила expires в nginx-конфигурацию.
  • Перезагрузить nginx безопасно (reload, проверка конфигурации nginx -t).
  • Протестировать заголовки curl и в браузере.

Frontend-разработчик:

  • Включить версионирование имён файлов в сборочной цепочке.
  • Проверить поддержку immutable и совместимость с CI/CD.

QA:

  • Проверить, что страницы с приватными данными не кэшируются.
  • Проверить, что новая версия ресурса загружается после смены имени файла.

Мини-методология внедрения (шаг за шагом)

  1. Проанализируйте список статических ресурсов и решите, какие можно кэшировать долго.
  2. Добавьте блок location в конфиг nginx с expires для выбранных типов файлов.
  3. Примените конфигурацию и проверьте nginx -t, затем reload.
  4. Протестируйте с curl и в браузере; проверьте работу через CDN.
  5. Настройте процесс сборки фронтенда на добавление хэшей/версий в имена файлов.
  6. Мониторьте инциденты, связанные с устаревшими ассетами, и обновляйте процедуру при релизах.

Факт-бокс — полезные числа

  • 1 год = 31536000 секунд (примерное значение, используется в директиве max-age).
  • 10 лет (значение, используемое директивой max) ≈ 315360000 секунд.
  • units: ms, s, m, h, d, w, M (30d), y (365d).

Критерии приёмки

  • Заголовки Expires и/или Cache-Control присутствуют для всех целевых статических ресурсов.
  • Для версионируемых файлов срок кэширования установлен в long-term (например, 365d) и новый файл скачивается при смене имени.
  • Никогда не кэшируются приватные страницы.

Советы по безопасности и конфиденциальности

  • Не добавляйте заголовки долгого кэширования к ответам, содержащим персональные данные.
  • При использовании CDN убедитесь, что правила кэширования не приводят к утечке пользовательских данных (учёт cookie и заголовков).

Справка и глоссарий

  • Expires — HTTP-заголовок с датой, после которой ресурс считается устаревшим.
  • Cache-Control — директива управления кэшированием; max-age указывает время жизни в секундах.
  • Версионирование — практический приём смены имени файла при изменении содержимого, чтобы принудить скачивание новой копии.

Ссылки

Об авторе

Falko Timme — владелец Timme Hosting и главный поддерживающий HowtoForge. Один из разработчиков ISPConfig и автор материалов по администрированию Linux.

Краткое резюме

  • Используйте expires в nginx для управления Expires и Cache-Control.
  • Версионируйте файлы, если используете дальнюю дату истечения.
  • Тестируйте через curl и инструменты разработчика браузера.
  • Не кэшируйте приватные данные и согласуйте правила с CDN при использовании.
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Несколько аккаунтов Skype: Multi Skype Launcher
Программное обеспечение

Несколько аккаунтов Skype: Multi Skype Launcher

Журнал для работы: повысить продуктивность
Productivity

Журнал для работы: повысить продуктивность

Персональные звуки уведомлений на Android
Android.

Персональные звуки уведомлений на Android

Скачивание шоу Hulu для офлайн‑просмотра
Стриминг

Скачивание шоу Hulu для офлайн‑просмотра

Microsoft Start: персонализированная новостная лента
Новости

Microsoft Start: персонализированная новостная лента

Как изменить имя в Epic Games быстро
Гайды

Как изменить имя в Epic Games быстро