Кеширование ответов на основе заголовков даты и возраста

Jan 17 2021

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

Вот простой пример заголовков, которые мы видим в ответе (запрос был отправлен, а ответ получен Sat, 16 Jan 2021 00:40:36 GMT):

date: Sat, 16 Jan 2021 00:40:36 GMT
age: 6
expires: Sat, 16 Jan 2021 00:40:40 GMT
last-modified: Sat, 16 Jan 2021 00:40:30 GMT

Из того, что я видел, глядя на CacheStrategy, проблема в том, что он складывает дату + возраст, чтобы увидеть, не истек ли срок его действия. В этом случае 00:40:36 + 6 = 00:40:42 > 00:40:40он не добавляется в кеш.

Поэтому я думаю, что в идеале либо дата ответа будет равна дате последнего изменения (в данном случае суббота, 16 января 2021 г., 00:40:30 по Гринвичу), либо нам понадобится настраиваемая CacheStrategy, чтобы использовать последнее изменение вместо дата для этих расчетов.

Если у кого-то есть понимание, делаю ли я какие-либо неверные предположения, или если один из вышеперечисленных вариантов предпочтительнее, сообщите мне. Я просмотрел некоторые спецификации для заголовков даты / возраста, и мне немного неясно, какими они должны быть в этом сценарии.

Мне также было немного сложно отладить поведение кеширования в OkHttp, прямо сейчас я просто использовал условные точки останова, чтобы попытаться отследить его, но если у кого-то есть идея получше, я тоже был бы признателен.

Ответы

2 JesseWilson Jan 22 2021 at 11:32

Замените expiresзаголовок заголовком Cache-Control, который устанавливает директиву max-age:

Cache-Control: max-age=86400

Это заставит OkHttp кэшировать ответ на 24 часа независимо от того, когда он был обслужен. Заголовок expires был проблематичным, потому что CloudFlare рассматривал его как конкретное время истечения, а не как продолжительность.

1 Menelaos Jan 26 2021 at 01:57

Я бы рекомендовал попробовать использовать заголовок «Cache-Control» с выбранным max-ageвами.

Основная причина, по которой я это делаю, заключается в том, что это также показано в примере из официальной документации, см.: https://square.github.io/okhttp/interceptors/#rewriting-responses

.header("Cache-Control", "max-age=60")

Очевидно, что предпочтительный способ сделать это - на стороне сервера. Если вы не можете изменить серверную часть, я думаю, что перехватчик будет вторым вариантом. Обратите внимание, что это последний вариант, который не рекомендуется.

В дополнение к вашему бэкэнду, я бы также посмотрел на параметры, которые предоставляет сам cloudflare: https://support.cloudflare.com/hc/en-us/articles/360021806811-Getting-Started-with-Cloudflare-Caching