Ответ
Кэширование 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 # Ответ предназначен только для одного пользователя (например, с персональными данными).
Важность для тестирования:
- Тестирование кэширования: Проверять, что ответы на
GET-запросы к статичным ресурсам возвращают корректные заголовки (Cache-Control,ETag,Last-Modified). - Предотвращение ошибок: Убедиться, что ответы на
POST,PUT,DELETEникогда не имеют заголовков, разрешающих их кэширование (public,max-age), чтобы избежать потери данных или некорректного поведения клиентов. - Инвалидация кэша: Проверять механизмы инвалидации кэша (например, использование
POSTдля изменения ресурса должно делать неактуальным кэш связанногоGET-запроса).
Ответ 18+ 🔞
А, слушай, смотри, вот эта вся хуйня с кэшированием HTTP-ответов — это, блядь, не просто так, наобум. Тут, сука, железная логика, как у Герасима из рассказа — либо так, либо нихуя.
Вот представь, сервер — это такой здоровый, молчаливый чувак, а кэш — это его собачка Муму, которая запоминает, что он сказал в прошлый раз, чтобы не орать одно и то же постоянно. Но, блядь, не все слова собачке доверять можно!
Кому НЕЛЬЗЯ доверять, блядь, собачке-кэшу (она запомнит и потом нахуярит):
| Метод | В чём, сука, подвох? |
|---|---|
POST |
Это ж, ёпта, создание нового! Каждый раз — уникальный пиздёныш. Если собачка запомнит ответ "201 Created" и будет его всем подряд тыкать, получится, что мы один заказ на все сто раз продублируем. Пиздец и разорение. |
PUT |
Хотя он и идемпотентный (ты его десять раз шлёшь — результат как от одного), он состояние меняет! Допустим, ты обновил цену. Собачка запомнила старый ответ "200 OK" и потом, когда ты захочешь посмотреть новую цену (GET), она тебе старую из своей пасти вытащит. Во какие, блядь, нахуй, распиздяйства! |
PATCH |
Это вообще, хитрая жопа, частичное обновление. Часто даже не идемпотентное. Меняет ресурс — значит, кэшу на него доверия ебать ноль. |
DELETE |
Ну тут вообще пиздец очевидный. Удалил ты товар, получил "204 No Content". Если это в кэш записать, то потом, когда кто-то попробует получить (GET) этот товар, кэш радостно выдаст "Всё чисто, братан!", хотя на самом деле там уже 404 Not Found и пустота. |
А кому МОЖНО, блядь?
-
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 # Это только для одного юзера (типа, его личный профиль). Не смей другим показывать, манда с ушами!
И что, блядь, со всем этим делать тестировщику?
- Проверяй, кто кэшируется: Гоняй
GET-запросы к статике (картинки, списки товаров). Смотри, чтобы в ответе были эти самыеCache-Control,ETagилиLast-Modified. Чтобы собачка знала, что ей делать. - Лови говнокод: Твоя святая обязанность — орать благим матом, если в ответе на
POST,PUTилиDELETEвдруг вылезетCache-Control: public, max-age=100500. Это пизда, это прямой путь к потере данных и пиздецу в продакшене. Нельзя! - Следи за инвалидацией: Вот, допустим, ты через
POSTсоздал новый отзыв. Так, блядь, проверь, что кэш на страницу товара (которая черезGETотдаётся) после этого стал невалидным. Чтобы новый отзыв сразу был виден, а не через пиздюлей пользователю приходилось кэш сбрасывать. Вот это и есть — волнение ебать, правильная работа!