Запрос/ответ кэширования браузера без заголовка Cache-Control

Я столкнулся с проблемой кеша браузера с веб-приложением SPA и серверной частью REST API. Я могу воспроизвести это в Firefox и Safari с открытыми инструментами разработчика: я убедился, что кеш НЕ отключен.

Когда я впервые перехожу на определенную страницу, которая просто извлекает и отображает объект из REST API, я делаю это с аппаратным обновлением (CMD+R на Mac). Я вижу следующие заголовки:

1-й запрос:

Host: localhost:5000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:77.0) Gecko/20100101 Firefox/77.0
Accept: application/json, text/plain, */*
Accept-Language: en,it;q=0.7,fr;q=0.3
Accept-Encoding: gzip, deflate, br
Origin: http://localhost:3000
DNT: 1
Connection: keep-alive
Referer: http://localhost:3000/literature/sde5e-zeb98
Cookie: ...
If-Modified-Since: Fri, 10 Jul 2020 16:19:24 GMT
If-None-Match: "2"
Cache-Control: max-age=0

(обратите внимание на заголовок Cache-Control, добавленный автоматически из-за жесткого обновления)

Ответ:

HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 6128
ETag: "2"
Last-Modified: Fri, 10 Jul 2020 16:19:24 GMT
Link: <https://localhost:5000/api/documents/sde5e-zeb98>; rel="self"
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 52
X-RateLimit-Reset: 1594398279
Retry-After: 60
X-Frame-Options: sameorigin
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31556926; includeSubDomains
Referrer-Policy: strict-origin-when-cross-origin
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Expose-Headers: Content-Type, ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
Access-Control-Allow-Credentials: true
Vary: Origin
Server: Werkzeug/1.0.1 Python/3.6.7
Date: Fri, 10 Jul 2020 16:23:38 GMT

Запрос достигает серверной части, как и ожидалось, я регистрирую его. Бэкэнд возвращает заголовки ETag + Last modified, но не возвращает заголовки других кэшей (например, max-age). Я хочу, чтобы браузер всегда попадал в бэкэнд.

Проблема возникает, когда я не нажимаю жесткое обновление, а просто перехожу на веб-сайте на другую страницу, а затем снова перехожу на эту страницу (не с помощью кнопки «Назад»), что в основном является обычным использованием веб-сайта. Я ожидаю, что браузер будет выполнять запрос к серверной части каждый раз, серверная часть возвращает код состояния ETag и 200/304, а браузер соответственно использует кеш клиента (расчет ETag на серверной части правильный). Проблема в том, что запрос даже не доходит до бэкэнда, не выполняется запрос, нет попадания в бэкэнд и я не понимаю почему. Я вижу в Firefox значение cached в столбце Transferred.

Ее просьба:

Host: localhost:5000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:77.0) Gecko/20100101 Firefox/77.0
Accept: application/json, text/plain, */*
Accept-Language: en,it;q=0.7,fr;q=0.3
Accept-Encoding: gzip, deflate, br
Origin: http://localhost:3000
DNT: 1
Connection: keep-alive
Referer: http://localhost:3000/literature/sde5e-zeb98
Cookie: ...

(нет заголовка Cache-Control, это правильно, это должно быть нормальным поведением)

Кэшированный ответ (без обращения к серверу):

HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 6128
ETag: "2"
Last-Modified: Fri, 10 Jul 2020 16:19:24 GMT
Link: <https://localhost:5000/api/documents/sde5e-zeb98>; rel="self"
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 52
X-RateLimit-Reset: 1594398445
Retry-After: 60
X-Frame-Options: sameorigin
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31556926; includeSubDomains
Referrer-Policy: strict-origin-when-cross-origin
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Expose-Headers: Content-Type, ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
Access-Control-Allow-Credentials: true
Vary: Origin
Server: Werkzeug/1.0.1 Python/3.6.7
Date: Fri, 10 Jul 2020 16:26:24 GMT

Я пытаюсь понять, какой заголовок останавливает браузер для выполнения запроса. У меня нет набора заголовков Cache-Control. Я подозреваю, что это может быть проблема с заголовком Vary, но любой намек приветствуется.

Любая идея, как отладить, почему браузер кэширует запрос? Какой заголовок неправильный? Спасибо!


person Nicola    schedule 10.07.2020    source источник


Ответы (1)


Отсутствие Cache-Control или Expires не означает, что кэширование отключено; это означает, что браузер может свободно реализовывать свою собственную политику кэширования. Как описано в RFC 7234:

Поскольку исходные серверы не всегда предоставляют явное время истечения срока действия, кэш МОЖЕТ назначать эвристическое время истечения срока действия, когда явное время не указано, используя алгоритмы, которые используют другие значения поля заголовка (например, время Last-Modified) для оценки вероятного времени истечения срока действия.

политика кэширования, которую вы действительно хотите это Cache-Control: no-cache, поэтому верните его.

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

person Kevin Christopher Henry    schedule 11.07.2020
comment
здесь и здесь другие хорошие объяснения этой проблемы. - person Nicola; 23.07.2020