我正在使用chrome上的服务工作者来缓存网络响应。当客户端请求资源时我打算做什么:
检查缓存 - 如果存在,则从缓存返回,但如果文件与缓存版本不同,还会向服务器发送请求并更新缓存。 如果缓存没有缓存,请向服务器发送请求,然后缓存响应。
这是我目前执行相同操作的代码:
self.addEventListener('fetch', function (event) {
var requestURL = new URL(event.request.url);
var freshResource = fetch(event.request).then(function (response) {
if (response.ok && requestURL.origin === location.origin) {
// All good? Update the cache with the network response
caches.open(CACHE_NAME).then(function (cache) {
cache.put(event.request, response);
});
}
// Return the clone as the response would be consumed while caching it
return response.clone();
});
var cachedResource = caches.open(CACHE_NAME).then(function (cache) {
return cache.match(event.request);
});
event.respondWith(cachedResource.catch(function () {
return freshResource;
}));
});
此代码无效,因为它会抛出错误:
url 的FetchEvent导致网络错误响应:一个不是响应的对象被传递给respondWith()。
有人能指出我正确的方向吗?
答案 0 :(得分:3)
好的,在人们指出建议(谢谢你)并找到解决方案之后,我摆弄了代码。
self.addEventListener('fetch', function (event) {
var requestURL = new URL(event.request.url);
var freshResource = fetch(event.request).then(function (response) {
var clonedResponse = response.clone();
// Don't update the cache with error pages!
if (response.ok) {
// All good? Update the cache with the network response
caches.open(CACHE_NAME).then(function (cache) {
cache.put(event.request, clonedResponse);
});
}
return response;
});
var cachedResource = caches.open(CACHE_NAME).then(function (cache) {
return cache.match(event.request).then(function(response) {
return response || freshResource;
});
}).catch(function (e) {
return freshResource;
});
event.respondWith(cachedResource);
});
整个问题源于缓存中没有项目且cache.match
返回错误的情况。在这种情况下,我需要做的就是获取实际的网络响应(注意return response || freshResource
)
这个答案对我来说是Aha!
时刻(尽管实施方式不同):
Use ServiceWorker cache only when offline