Признать протокол HTTP 304 работник службы / принеси()
Я создаю Service worker, который всегда отвечает данными из кэша, а затем в фоновом режиме отправляет запрос на сервер. Если сервер отвечает HTTP 304 - not modified все в порядке, если сервер отвечает HTTP 200, это означает, что данные были изменены и новый файл помещен в кэш, также пользователь уведомляется и просит обновить страницу.
Я использую not-modified-since / last-modified заголовки, чтобы убедиться, что клиент получает самую последнюю версию. Когда запрос отправляется через fetch() запрос передает HTTP-кэш по пути в сеть - также ответ передает http-кэш, когда он поступает на клиент. Проблема заключается в том, что когда ответ имеет статус 304 - не изменен, кэш HTTP отвечает работнику службы с кэшированной версией и заменяет статус на 200 (как описано в спецификации fetch - HTTP-network-or-cache-fetch). В сервисном работнике нет возможности узнать, был ли изначально отправлен ответ 200 сервер (пользователь должен быть обновлен) или он был отправлен кэшем и сервер первоначально ответил 304 (самая последняя версия уже загружена).
Существует флагрежима кэширования , который может быть установлен в no-cache, но это обходит HTTP-кэш также при отправке запроса на сервер, что означает, что заголовок if-modified-since не установлен и сервер не имеет возможности узнать, какая версия у клиента. Также этот флаг поддерживается только firefox nightly right сейчас.
Я думаю, что лучшее решение-это установить пользовательский заголовок HTTP, такой как x-was-modified, когда сервер отвечает 200. Этот пользовательский заголовок доступен в Service worker и может использоваться для определения того, был ли ресурс обновлен или нет, даже если кэш HTTP заменяет состояние 304 на 200.
- Является ли это законным решением / обходным путем? Существуют ли какие-либо предлагаемые подходы к решению этой проблемы?
- должен ли я вообще полагаться на заголовки HTTP, которые должны обрабатывать http-кэширования при реализации кэша работник сервиса? Или мне лучше использовать обычай
x-if-modified-since/x-last-modifiedзаголовки и использовать indexedDB для хранения информации о клиенте и добавлять ее к каждому запросу? - Почему
fetch()даже заменяет код304на200, если в кэше есть последняя версия?
1 ответ:
Вы не можете полагаться на код состояния (304 против 200), чтобы определить, изменилось ли что-то. Что делать, если какая-то другая часть вашего кода запрашивает тот же ресурс, обновляя таким образом кэш браузера?
Вместо этого просто сравните заголовок ответаLast-Modifiedс тем, что вы отправили вIf-Modified-Since, или с тем, что вы в последний раз видели вLast-Modified. Если значения не совпадают, значит, что-то изменилось.Для большей точности (если данные могут изменяться несколько раз за 1 секунду), рассмотрите возможность использования
ETagвместо этого изLast-Modified.Потому что обычно люди просто хотят получить свежий контент, независимо от того, откуда он берется. Ответ 304 интересен только тем, кто реализует свои собственные HTTP-кэши.Почему
fetch()даже заменяет код304на200, Если в кэше есть последняя версия?