middle
Как работает HTTP-кэширование?
HTTP-кэширование — это механизм протокола HTTP, позволяющий клиенту (браузеру) и промежуточным серверам (CDN, proxy) хранить и переиспользовать ответы сервера без повторного обращения к нему.
Заголовки кэширования
Пример
HTTP/1.1 200 OK
Cache-Control: max-age=3600, public
ETag: "abc123"
Last-Modified: Tue, 22 Apr 2026 10:00:00 GMT
| Заголовок | Назначение | Пример |
|---|---|---|
Cache-Control |
Управление кэшированием | max-age=3600, public |
ETag |
Хэш содержимого для условных запросов | "abc123" |
Last-Modified |
Дата последнего изменения | Tue, 22 Apr 2026 10:00:00 GMT |
Vary |
По каким заголовкам различать кэш | Vary: Accept-Encoding |
Директивы Cache-Control
| Директива | Значение |
|---|---|
public |
Можно кэшировать где угодно (CDN, proxy) |
private |
Только в браузере (содержит персональные данные) |
no-cache |
Кэшировать, но всегда проверять актуальность (через ETag/Last-Modified) |
no-store |
Не кэшировать вообще (sensitive данные) |
max-age=N |
Свежесть в секундах |
must-revalidate |
После истечения max-age обязательно проверить |
Условные запросы (conditional requests)
Пример
1. Первый запрос:
GET /api/products/1 → 200 OK, ETag: "abc123"
2. Повторный запрос (с ETag):
GET /api/products/1
If-None-Match: "abc123"
3. Если данные не изменились:
304 Not Modified (тело НЕ передаётся — экономия трафика)
4. Если изменились:
200 OK, ETag: "def456", новое тело
Реализация в Spring
Пример
@GetMapping("/products/{id}")
public ResponseEntity<Product> getProduct(@PathVariable Long id) {
Product product = productService.findById(id);
String etag = "\"" + product.getVersion() + "\"";
return ResponseEntity.ok()
.cacheControl(CacheControl.maxAge(Duration.ofMinutes(10)).cachePublic())
.eTag(etag)
.body(product);
}
// Или с Spring ShallowEtagHeaderFilter (автоматический ETag по содержимому)
@Bean
public FilterRegistrationBean<ShallowEtagHeaderFilter> etagFilter() {
return new FilterRegistrationBean<>(new ShallowEtagHeaderFilter());
}
Ключевые принципы
Cache-Control: no-cacheНЕ означает “не кэшировать”; это “кэшировать, но проверять актуальность”Cache-Control: no-store— единственный способ полностью запретить кэширование- ETag +
If-None-Matchдают 304 Not Modified — экономия трафика без потери актуальности - CDN кэширует только
publicответы
Частые ошибки
- Не устанавливать
Cache-Control— браузер может кэшировать по эвристике, или не кэшировать вообще no-cacheвместоno-store— путаница;no-cacheвсё ещё кэширует- Кэшировать персональные данные как
public— CDN может отдать чужие данные - Забыть
Vary: Authorization— ответы для разных пользователей смешиваются в кэше
Как используется в 2026
- CDN (Cloudflare, CloudFront) — стандарт для статики и API
stale-while-revalidate— директива Cache-Control для фонового обновления- API Gateway (Spring Cloud Gateway, Nginx) — кэширование на уровне gateway
На собеседовании: интервьюер обязательно спросит разницу между
no-cacheиno-store— это классическая ловушка. Частая ошибка — думать, чтоno-cacheзапрещает кэширование.