Какие HTTP-методы, как правило, не подлежат кэшированию и почему?

«Какие HTTP-методы, как правило, не подлежат кэшированию и почему?» — вопрос из категории HTTP и веб-протоколы, который задают на 10% собеседований QA Тестировщик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Кэширование HTTP-ответов в основном применимо к безопасным (Safe) и идемпотентным (Idempotent) методам. Методы, изменяющие состояние сервера, обычно не кэшируются.

Методы, которые НЕ кэшируются (или кэшируются с крайними ограничениями):

Метод Почему не кэшируется
POST Создает новый ресурс. Каждый запрос потенциально уникален и приводит к изменению состояния сервера. Кэширование ответа POST (например, 201 Created) и его повторное использование для другого запроса привело бы к некорректному поведению.
PUT Хотя идемпотентен, он изменяет состояние ресурса. Кэширование ответа на PUT (например, 200 OK) и его выдача на последующий GET к тому же ресурсу может вернуть устаревшие данные, так как PUT их обновил. Кэшируются с большой осторожностью, обычно с Cache-Control: no-cache или max-age=0.
PATCH Частичное обновление, часто неидемпотентно. Как и PUT, изменяет ресурс, поэтому кэширование ответов не рекомендуется.
DELETE Удаляет ресурс. Ответ (например, 204 No Content или 200 OK) не имеет смысла кэшировать, так как последующий GET к этому URI должен вернуть 404 Not Found.

Методы, которые МОГУТ кэшироваться:

  • GET: Основной кандидат для кэширования. Ответы GET можно безопасно кэшировать, если они не содержат персональных или часто меняющихся данных.

    GET /api/products HTTP/1.1
    Host: example.com

    Ответ может включать заголовки для кэширования:

    HTTP/1.1 200 OK
    Cache-Control: public, max-age=3600
    Content-Type: application/json
    
    [{"id": 1, "name": "Product A"}]
  • HEAD: Аналогичен GET, кэшируются только заголовки ответа.

Правила кэширования определяются заголовками: Даже для GET кэширование может быть отключено, если ответ содержит:

Cache-Control: no-store          # Запрещает хранить ответ где бы то ни было.
Cache-Control: no-cache          # Ответ можно кэшировать, но перед использованием необходимо проверить его свежесть с сервером.
Cache-Control: private           # Ответ предназначен только для одного пользователя (например, с персональными данными).

Важность для тестирования:

  1. Тестирование кэширования: Проверять, что ответы на GET-запросы к статичным ресурсам возвращают корректные заголовки (Cache-Control, ETag, Last-Modified).
  2. Предотвращение ошибок: Убедиться, что ответы на POST, PUT, DELETE никогда не имеют заголовков, разрешающих их кэширование (public, max-age), чтобы избежать потери данных или некорректного поведения клиентов.
  3. Инвалидация кэша: Проверять механизмы инвалидации кэша (например, использование POST для изменения ресурса должно делать неактуальным кэш связанного GET-запроса).