Javascript service worker:从缓存中获取资源,同时更新它
Javascript service worker: Fetch resource from cache, but also update it
我在 chrome 上使用 service worker 来缓存网络响应。当客户端请求资源时我打算做什么:
检查缓存 - 如果存在,return 从缓存中检查缓存,但如果文件与缓存版本不同,也会向服务器发送请求并更新缓存。
如果缓存没有,向服务器发送请求,然后缓存响应。
这是我当前执行相同操作的代码:
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;
}));
});
此代码无效,因为它会引发错误:
The FetchEvent for url resulted in a network error response: an object that was not a Response was passed to respondWith().
谁能给我指出正确的方向?
好的,在大家提出建议(谢谢)后,我修改了代码并找到了解决方案。
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!
时刻(尽管实现方式不同):
我在 chrome 上使用 service worker 来缓存网络响应。当客户端请求资源时我打算做什么:
检查缓存 - 如果存在,return 从缓存中检查缓存,但如果文件与缓存版本不同,也会向服务器发送请求并更新缓存。 如果缓存没有,向服务器发送请求,然后缓存响应。
这是我当前执行相同操作的代码:
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;
}));
});
此代码无效,因为它会引发错误:
The FetchEvent for url resulted in a network error response: an object that was not a Response was passed to respondWith().
谁能给我指出正确的方向?
好的,在大家提出建议(谢谢)后,我修改了代码并找到了解决方案。
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!
时刻(尽管实现方式不同):