Eri*_*rik 6 javascript caching http browser-cache 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;
Run Code Online (Sandbox Code Playgroud)
我得到的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);
Run Code Online (Sandbox Code Playgroud)
遗憾的是,此解决方案不起作用,因为网络响应不可变.顺便说一句:复制响应以添加此附加信息不是一种选择.
有人知道如何正确识别浏览器等陈旧缓存条目吗?
遗憾的是,该解决方案不起作用,因为网络响应不可变。顺便说一句:复制响应来添加此附加信息不是一个选项。
这实际上是完全可行的。
解决此问题的一种方法是创建一个新的Response 对象并手动添加新标头。
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
})
})
Run Code Online (Sandbox Code Playgroud)
另一个更简单但黑客的解决方案是在响应对象上创建一个新属性,而不是依赖于 headers 对象:
response.__time_fetched = new Date()
Run Code Online (Sandbox Code Playgroud)