Какие методы браузер может кэшировать?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
HTTP методы и кэширование браузера
Понимание того, какие HTTP методы браузер может кэшировать — это фундаментальное знание для разработчика, работающего с REST API и веб-приложениями. Это напрямую влияет на производительность и правильность приложения.
Методы, которые браузер МОЖЕТ кэшировать
GET — наиболее часто кэшируемый метод:
- Браузер автоматически кэширует GET запросы
- Использует HTTP headers для управления кэшем:
Cache-Control: max-age=3600Expires: Wed, 21 Mar 2026 07:28:00 GMTETagдля валидации кэшаLast-Modifiedдля проверки изменений
Пример:
@GetMapping("/api/v1/users/{id}")
@CacheEvict(cacheNames = "users", key = "#id")
public ResponseEntity<UserDTO> getUser(@PathVariable String id) {
return ResponseEntity.ok()
.cacheControl(CacheControl.maxAge(1, TimeUnit.HOURS))
.body(userService.findById(id));
}
HEAD — может быть кэширован
- Идентичен GET по поведению кэширования
- Не содержит body в ответе
- Используется для проверки существования ресурса
OPTIONS — может быть кэширован
- Браузер кэширует информацию о допустимых методах
- Используется для CORS preflight запросов
Методы, которые браузер НЕ кэширует
POST — по умолчанию НЕ кэшируется:
- Предназначен для создания новых ресурсов
- Изменяет состояние сервера
- Кэширование может привести к проблемам
Однако, возможно кэширование POST через явный заголовок (редко используется):
@PostMapping("/api/v1/search")
public ResponseEntity<List<SearchResult>> search(@RequestBody SearchQuery query) {
// Если POST идемпотентный (например, поиск)
return ResponseEntity.ok()
.cacheControl(CacheControl.maxAge(5, TimeUnit.MINUTES))
.body(searchService.search(query));
}
PUT — не кэшируется браузером
- Используется для обновления существующих ресурсов
- Побочные эффекты при кэшировании
DELETE — не кэшируется браузером
- Удаляет ресурсы
- Кэширование критически опасно
PATCH — не кэшируется браузером
- Частичное обновление ресурса
- Идентично PUT по рискам кэширования
Механизмы управления кэшем
Cache-Control header — главный инструмент:
public— может быть кэширован любым кэшемprivate— только браузер (не shared caches)no-cache— валидировать с сервером перед использованиемno-store— не кэшировать совсемmax-age=seconds— время жизни кэшаmust-revalidate— после истечения переспросить сервер
@GetMapping("/api/v1/posts/{id}")
public ResponseEntity<PostDTO> getPost(@PathVariable String id) {
return ResponseEntity.ok()
.cacheControl(CacheControl.maxAge(1, TimeUnit.HOURS)
.cachePublic()
.mustRevalidate())
.body(postService.findById(id));
}
ETag — условное кэширование:
- Сервер генерирует хеш содержимого
- Браузер проверяет:
If-None-Match: "e4aff01234abcd1234" - Если не изменилось — ответ 304 Not Modified
@GetMapping("/api/v1/data")
public ResponseEntity<DataDTO> getData() {
DataDTO data = dataService.getData();
String etag = "\"" + data.hashCode() + "\"";
return ResponseEntity.ok()
.eTag(etag)
.cacheControl(CacheControl.noCache())
.body(data);
}
Last-Modified — временное кэширование:
- Сервер указывает дату изменения ресурса
- Браузер проверяет:
If-Modified-Since: Wed, 21 Mar 2025 07:28:00 GMT - При совпадении — 304 Not Modified
Практические примеры
Кэшируемые ресурсы (GET):
- Статические файлы (CSS, JS, изображения)
- API ответы с исторических данных
- Неизменяемые профили пользователей
- Каталоги товаров
НЕ кэшируемые операции:
- Аутентификация (POST /login)
- Изменение профиля (PUT /profile)
- Удаление ресурсов (DELETE)
- Личные данные (кэш = security risk)
Кэширование в контексте микросервисов
В распределенной архитектуре:
@RestController
@RequestMapping("/api/v1/catalog")
public class ProductController {
@GetMapping("/{id}")
public ResponseEntity<ProductDTO> getProduct(@PathVariable String id) {
// CDN может кэшировать это
return ResponseEntity.ok()
.cacheControl(CacheControl.maxAge(24, TimeUnit.HOURS).cachePublic())
.body(productService.findById(id));
}
@PostMapping()
public ResponseEntity<ProductDTO> createProduct(@RequestBody CreateProductRequest req) {
// POST НЕ кэшируется (кроме явного указания)
return ResponseEntity.created(uri).body(productService.create(req));
}
@PutMapping("/{id}")
public ResponseEntity<ProductDTO> updateProduct(
@PathVariable String id,
@RequestBody UpdateProductRequest req) {
// PUT не кэшируется
// Должны инвалидировать кэш GET запроса
productService.update(id, req);
return ResponseEntity.ok().build();
}
}
Инвалидация кэша
При изменении данных нужно инвалидировать кэш:
@PutMapping("/{id}")
@CacheEvict(cacheNames = "products", key = "#id")
public ResponseEntity<ProductDTO> updateProduct(
@PathVariable String id,
@RequestBody UpdateProductRequest req) {
return ResponseEntity.ok(productService.update(id, req));
}
Заключение
В HTTP-спецификации:
- GET, HEAD, OPTIONS могут быть кэшированы браузером
- POST обычно не кэшируется (но технически может)
- PUT, DELETE, PATCH не кэшируются
Напомню: правильное использование кэша требует понимания Cache-Control, ETag и Last-Modified headers. Это критически важно для оптимизации производительности приложения.