Определите устаревшие записи в кэше Service Worker - PullRequest
0 голосов
/ 13 июня 2018

Я хочу, чтобы мой Service Worker в некоторых ситуациях вел себя как кеш браузера.Это означает, что при ответе на попадание в кэш я должен сначала убедиться, что ресурс не истек.Я могу сделать это, например, так:

const cacheControl = response.headers.get('cache-control');
const date = new Date(response.headers.get('date'));
const age = parseInt(response.headers.get('age') || '0', 10);

const maxAge = getMaxAge(cacheControl);
const expiration = date.getTime() + 1000 * (maxAge - age);

const isFresh = Date.now() < expiration;

Я получаю заголовки cache-control, date и age из кэшированного ответа, вычисляю срок действия и сравниваю с текущим временем.

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

Представьте, что время клиента отключено на один день (что, к сожалению, иногда случается), теперь записи в кэшеможет кэшироваться на день дольше или короче, чем предполагалось.

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

const networkResponse = fetch(request);
// does not work, headers are immutable
networkResponse.headers.append('x-time-fetched', Date.now());
cach.put(request, networkResponse);

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

Есть ли у кого-нибудь идеи, как правильно идентифицировать устаревшие записи в кэше, такие как браузер?

1 Ответ

0 голосов
/ 26 июня 2018

К сожалению, это решение не работает, потому что сетевой ответ не является изменяемым.Кстати: копирование ответа для добавления этой дополнительной информации не вариант.

Это на самом деле вполне выполнимо.

Одним из решений этой проблемы было бы создание нового Ответа.объект и добавление нового заголовка вручную.

const newHeaders = new Headers()
for (let entry of response.headers.entries()) {
  headers.append(entry[0], entry[1])
}
headers.append('x-time-fetched', Date.now())

const newResponse = await response.blob().then(blob => {
  return new Response(blob, {
    status: response.status,
    statusText: res.statusText,
    headers: headers
  })
})

Другое простое, но хакерское решение - просто создать новое свойство для объекта ответа вместо зависимости от объекта заголовков:

response.__time_fetched = new Date()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...