Кэшируются ли PUT-запросы по HTTP?

Ответ

Как правило, ответы на PUT-запросы не кэшируются. Это определяется стандартами HTTP и семантикой метода.

Причины:

  • Идемпотентность, но не кэшируемость: PUT является идемпотентным (многократное выполнение дает тот же результат), но его основная цель — обновление или создание ресурса по конкретному URI. Кэширование такого ответа привело бы к тому, что последующие GET-запросы могли бы получить устаревшие данные.
  • Семантика изменения: PUT изменяет состояние ресурса на сервере. Кэши, включая прокси-серверы и браузеры, обычно считают такие ответы некэшируемыми по умолчанию.
  • Заголовки ответа: Сервер должен явно указать, что ответ можно кэшировать, используя заголовки типа Cache-Control. Для PUT это делается крайне редко.

Пример заголовков ответа, которые запрещают кэширование (типичный случай для PUT):

HTTP/1.1 200 OK
Cache-Control: no-store
Content-Type: application/json

{"status": "updated"}

Исключение: Теоретически, если сервер для успешного PUT-запроса возвращает представление обновленного ресурса и явно задает политику кэширования (например, Cache-Control: public, max-age=3600), то ответ может быть закэширован. Однако на практике такая конфигурация встречается редко и требует осторожности, чтобы не нарушить согласованность данных.

Ответ 18+ 🔞

Давай разжую эту тему так, чтобы даже твой кот, если он случайно на клавиатуру наступит, всё понял.

Вообще, по умолчанию, ответы на PUT-запросы не кэшируются. Вообще нихуя. И это не просто так, а потому что сама суть этого метода — ебануть данные на сервер, чтобы их обновить или создать.

Представь: ты отправляешь PUT-запрос, чтобы поменять своё имя в профиле с "Вася Пупкин" на "Грозный Повелитель Всея Офиса". Сервер отвечает: "Окей, ёпта, поменял, вот тебе подтверждение". Если бы этот ответ закэшировался, то следующий человек, который захочет посмотреть твой профиль (GET-запрос), мог бы получить из кэша старое "Вася Пупкин". И какой же ты после этого Грозный Повелитель? Просто Вася, блядь.

Почему так?

  1. Семантика, ёпта! PUT — это про изменение состояния. Его задача — не просто что-то отдать, а что-то сделать с ресурсом. Кэши по умолчанию к таким ответам относятся с подозрением, как к незнакомцу в тёмном переулке — "а вдруг он что-то у нас тут поменяет?".
  2. Стандарты говорят. Спецификация HTTP хоть и не запрещает кэширование PUT намертво, но прямо указывает, что ответы на методы, меняющие состояние, по умолчанию не должны считаться кэшируемыми, если явно не указано обратное.

Типичный ответ на PUT выглядит так, что любая уважающая себя прокси или браузер сразу поймёт: "Э, нет, это в кэш класть не будем".

HTTP/1.1 200 OK
Cache-Control: no-store  // <-- Видишь эту строчку? Это приговор для кэша. "Не храни, нахуй, вообще."
Content-Type: application/json

{"status": "updated", "message": "Имя успешно поменяно на 'Грозный Повелитель'"}

А бывают исключения? Теоретически — да, если очень захотеть. Сервер может в ответ на PUT вернуть, например, свежее представление обновлённого ресурса и явно сказать: "Вот это, кстати, можешь закэшировать на час". Типа Cache-Control: public, max-age=3600.

Но на практике это такая редкая хуйня, что её в учебниках приводят как диковинку. Потому что слишком велик риск, что где-то в цепочке какой-нибудь промежуточный кэш проигнорирует эти указания или закэширует что-то не то, и получится пиздец с данными. Зачем тебе эти грабли?

Короче, вывод простой: Работай с PUT так, будто кэша не существует. Рассчитывай, что ответ не закэшируется, и будешь прав в 99.9% случаев. А если вдруг где-то встретишь обратное — это такой же феномен, как единорог, и к нему надо прилагать трёхметровую инструкцию для всех, кто будет это поддерживать.