Загрузка...
Загрузка...
Настройка HTTP-кэширования: Cache-Control, ETag, Last-Modified, stale-while-revalidate. Стратегии для статики, HTML и API. Примеры для Nginx и Node.js.
Полное руководство по кэшированию в веб-разработке. HTTP-кэширование, Service Workers, CDN, кэширование на сервере и в базе данных. Практические стратегии для ускорения сайтов.
БезопасностьПолное руководство по настройке Brotli сжатия на веб-серверах: Nginx, Apache, сравнение с Gzip, уровни сжатия и проверка работы.
БезопасностьПолное руководство по CSP: все директивы, nonce, hash, report-uri, strict-dynamic. Пошаговое внедрение, отладка, примеры для популярных фреймворков.
БезопасностьПрактическое руководство по настройке Content Security Policy для защиты от XSS. Директивы, примеры конфигурации, режим Report-Only и внедрение без поломки сайта.
Поделитесь с коллегами или изучите другие материалы блога
Правильная настройка кэширования снижает нагрузку на сервер и ускоряет загрузку сайта. Браузер и CDN используют HTTP-заголовки, чтобы решить: сохранять ли ответ в кэш, как долго его хранить и когда запрашивать обновление. Неверные настройки приводят к устаревшему контенту или, наоборот, к лишним запросам.
Проверить текущие заголовки кэширования можно через HTTP Headers Analyzer и Web Vitals для оценки влияния на производительность.
Cache-Control, ETag, Expires.If-None-Match (ETag) или If-Modified-Since.Подробнее о всех HTTP-заголовках — в HTTP заголовки: полный справочник для разработчика.
Cache-Control: max-age=3600
max-age — время в секундах, в течение которого ответ считается свежим. После истечения браузер может отправить условный запрос для валидации.
Cache-Control: public, max-age=86400
| Значение | Описание |
|---|---|
| public | Можно кэшировать в CDN, прокси, браузере |
| private | Только в браузере пользователя (персональные данные) |
Cache-Control: no-store
Ответ не сохраняется. Для чувствительных данных (банковские операции, персональная информация).
Cache-Control: no-cache
Кэш можно хранить, но перед использованием нужна валидация у сервера (через ETag или Last-Modified).
Cache-Control: public, max-age=3600, s-maxage=86400
s-maxage — время жизни в shared cache (CDN, прокси). Браузер использует max-age.
Cache-Control: max-age=3600, stale-while-revalidate=600
Пока идёт повторная валидация (до 600 секунд), браузер может отдать устаревший контент. Улучшает perceived performance.
ETag — хеш или идентификатор версии контента. При повторном запросе браузер отправляет:
If-None-Match: "abc123"
Если контент не изменился, сервер отвечает:
HTTP/1.1 304 Not Modified
ETag: "abc123"
Тело ответа не передаётся — экономия трафика.
ETag: W/"abc123"
W/ означает weak ETag — контент семантически эквивалентен, но байт-в-байт может отличаться (например, пробелы).
Альтернатива ETag — дата последнего изменения:
Last-Modified: Wed, 21 Oct 2025 07:28:00 GMT
При повторном запросе:
If-Modified-Since: Wed, 21 Oct 2025 07:28:00 GMT
Сервер сравнивает дату и при отсутствии изменений отдаёт 304.
Expires: Thu, 31 Dec 2025 23:59:59 GMT
Проблемы: зависимость от точности часов клиента, негибкость. Предпочтительно использовать Cache-Control: max-age.
Vary: Accept-Encoding, User-Agent
Указывает, что ответ зависит от этих заголовков запроса. Кэш хранит отдельные варианты для разных комбинаций. Важно для контента, зависящего от языка, устройства или кодировки.
Файлы вида main.a1b2c3d4.js, style.e5f6g7h8.css — при изменении контента меняется имя. Можно кэшировать надолго:
Cache-Control: public, max-age=31536000, immutable
Cache-Control: public, max-age=86400, must-revalidate
Короткий кэш с обязательной валидацией после истечения.
Cache-Control: no-cache
Или max-age=0, must-revalidate — всегда валидировать перед использованием. HTML часто содержит ссылки на актуальные версии JS/CSS.
Cache-Control: private, no-store
Cache-Control: public, max-age=60, stale-while-revalidate=300
# Статика с хешем
location ~* \.[a-f0-9]{8,}\.(js|css)$ {
add_header Cache-Control "public, max-age=31536000, immutable";
}
# Обычная статика
location /static/ {
add_header Cache-Control "public, max-age=86400, must-revalidate";
}
# HTML
location / {
add_header Cache-Control "no-cache";
}
// Статика
app.use('/static', express.static('public', {
maxAge: '1y',
immutable: true,
etag: true,
lastModified: true
}));
// HTML
app.use((req, res, next) => {
if (req.path.endsWith('.html') || !req.path.includes('.')) {
res.setHeader('Cache-Control', 'no-cache');
}
next();
});
curl -I https://example.com/static/main.js
Ожидаемые заголовки:
Cache-Control: public, max-age=31536000, immutable
ETag: "abc123"
Онлайн: HTTP Headers — полный разбор заголовков ответа.
no-store.