Ответ
HTTP-ответ может быть кэширован, если он соответствует нескольким ключевым критериям, в основном связанным с методом запроса и заголовками ответа.
Основные условия для кэширования:
-
Метод запроса: Кэшируются в первую очередь безопасные и идемпотентные методы, такие как:
GET: Основной кандидат на кэширование, так как он предназначен для получения данных.HEAD: АналогиченGET, но без тела ответа.- Методы
POST,PUT,DELETE, изменяющие состояние на сервере, по умолчанию не кэшируются.
-
Код состояния ответа: Кэшируются успешные ответы или редиректы.
200 OK203 Non-Authoritative Information301 Moved Permanently404 Not Found(может кэшироваться, чтобы не запрашивать несуществующий ресурс повторно).
-
Заголовки управления кэшем в ответе: Сервер должен явно разрешить кэширование с помощью специальных заголовков.
Cache-Control: Современный и наиболее гибкий заголовок (например,max-age=3600,public,private).Expires: Устаревший заголовок, указывающий точную дату и время, когда кэш станет невалидным.
Пример кэшируемого ответа сервера:
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: public, max-age=86400
ETag: "abcdef123456"
{
"data": "some cached content"
}
Что может помешать кэшированию?
Cache-Control: no-store: Явный запрет на любое кэширование.Cache-Control: no-cache: Требует валидации с сервером перед использованием кэшированной версии.- Заголовок
Authorization: Ответы на запросы с этим заголовком обычно не кэшируются промежуточными прокси-серверами из соображений безопасности.
Ответ 18+ 🔞
А, ну это ж классика, блядь! Сидишь ты такой, делаешь запрос, а в ответе тебе прилетает какая-то хуйня, и ты думаешь: "Ну вот, опять всё с нуля качать". А оказывается, что сервер-то мог бы и закэшировать, да не захотел, сука!
Смотри, чтобы твой ответ застрял в кэше у клиента или какого-нибудь прокси, нужно соблюсти несколько правил. Не абы каких, а конкретных, блядь.
Первое, и главное — метод запроса.
Кэшируют в основном всякое безобидное дерьмо, которое ничего не меняет. GET — наш кандидат, HEAD — тоже. А вот если ты уже начал POSTить, PUTить или DELETEить — забудь, ёпта. Это ж операции, меняющие состояние, какой нахуй кэш? Тут уже не до шуток.
Второе — статус ответа.
Не любой код прокатит. Успешные (200 OK) — да. Редиректы постоянные (301) — да. Даже 404 могут закэшировать, чтобы не дергать сервер по поводу одной и той же несуществующей хуйни каждые пять секунд. А вот всякие 500 Internal Server Error или 403 Forbidden — это уже не в тему, их обычно не кэшируют.
И третье, самое важное — заголовки, блядь!
Сервер должен явно сказать: "Да, кэшируйте эту пиздопроебибну!". Как он это делает? Через заголовки!
Cache-Control— это наш современный царь и бог. Пишешь, например,public, max-age=86400— и всё, контент будет жить в кэше сутки. Красота!Expires— это старый дед, который ещё помнит IE6. Указывает точную дату, когда кэш протухнет. Но лучше использоватьCache-Control.
Вот смотри, как выглядит правильный, годный ответ, который все полюбят и закэшируют:
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: public, max-age=86400
ETag: "abcdef123456"
{
"data": "some cached content"
}
Видишь? Cache-Control есть, max-age указан. Всё, понеслась. Клиент будет целые сутки тыкаться в свой локальный кэш и не дергать сервак. Экономия трафика — овердохуищная!
А что всё портит?
А портит всё, как обычно, какая-нибудь хитрая жопа, которая перестраховывается.
Cache-Control: no-store— это полный и бесповоротный запрет. Никакого кэша, нигде, никогда. Жёстко, блядь.Cache-Control: no-cache— не "не кэшировать", а "кэшировать, но перед использованием спросить у сервера: 'А не обновилось ли чо?'". Постоянная валидация, одним словом.- Заголовок
Authorization— если запрос авторизованный (с токеном, куками), то промежуточные прокси-сервера обычно пиздят и не кэшируют такой ответ. Ну а чо, безопасность же, вдруг твои личные данные утекут какому-нибудь левому чуваку?
Вот и вся магия, не такая уж и сложная. Главное — не забывать эти заголовки ставить, а то народ потом ебётся, почему у них аппка тормозит и трафик жрёт как не в себя.