仅在离线时使用 ServiceWorker 缓存
Use ServiceWorker cache only when offline
我正在尝试将 service worker 集成到我的应用程序中,但我发现 service worker 即使在线时也会尝试检索缓存的内容,但我希望它在这些情况下更喜欢网络。我怎样才能做到这一点?下面是我现在拥有的代码,但我认为它不起作用。为简洁起见省略了软件安装代码。
var CACHE_NAME = 'my-cache-v1';
var urlsToCache = [
/* my cached file list */
];
self.addEventListener('install', function(event) {
// Perform install steps
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
console.log('Opened cache');
return cache.addAll(urlsToCache);
})
);
});
/* request is being made */
self.addEventListener('fetch', function(event) {
event.respondWith(
//first try to run the request normally
fetch(event.request).catch(function() {
//catch errors by attempting to match in cache
return caches.match(event.request).then(function(response) {
// Cache hit - return response
if (response) {
return response;
}
});
})
);
});
这似乎会导致警告,例如 The FetchEvent for "[url]" resulted in a network error response: an object that was not a Response was passed to respondWith().
我是服务人员的新手,因此对于任何错误的术语或不良做法深表歉意,欢迎任何提示。谢谢!
如果不对此进行测试,我的猜测是在没有缓存匹配的情况下您没有正确解析 respondWith()
。 According to MDN,传递给 respondWith()
的代码应该是 "resolve by returning a Response or network error to Fetch." 那么为什么不尝试这样做:
self.addEventListener('fetch', function(event) {
event.respondWith(
fetch(event.request).catch(function() {
return caches.match(event.request);
})
);
});
你为什么不为你的获取事件打开缓存?
我认为service worker的流程是:
打开缓存
检查请求是否与缓存中的答案匹配
那你回答
或(如果答案不在缓存中):
通过网络检查请求
从网络克隆你的答案
将请求和答案的克隆放入缓存中以备将来使用
我会写:
self.addEventListener('fetch', event => {
event.respondWith(
caches.open(CACHE_NAME).then(cache => {
return cache.match(event.request).then(response => {
return response || fetch(event.request)
.then(response => {
const responseClone = response.clone();
cache.put(event.request, responseClone);
})
})
}
);
});
event.respondWith() expects a promise that resolves to Response。因此,如果缓存未命中,您仍然需要 return 一个响应,但在上面,您什么都没有 return。我也会尝试先使用缓存,然后再获取,但无论如何,作为最后的手段,你总是可以创建一个合成的响应,例如这样的东西:
return new Response("Network error happened", {"status" : 408, "headers" : {"Content-Type" : "text/plain"}});
我正在尝试将 service worker 集成到我的应用程序中,但我发现 service worker 即使在线时也会尝试检索缓存的内容,但我希望它在这些情况下更喜欢网络。我怎样才能做到这一点?下面是我现在拥有的代码,但我认为它不起作用。为简洁起见省略了软件安装代码。
var CACHE_NAME = 'my-cache-v1';
var urlsToCache = [
/* my cached file list */
];
self.addEventListener('install', function(event) {
// Perform install steps
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
console.log('Opened cache');
return cache.addAll(urlsToCache);
})
);
});
/* request is being made */
self.addEventListener('fetch', function(event) {
event.respondWith(
//first try to run the request normally
fetch(event.request).catch(function() {
//catch errors by attempting to match in cache
return caches.match(event.request).then(function(response) {
// Cache hit - return response
if (response) {
return response;
}
});
})
);
});
这似乎会导致警告,例如 The FetchEvent for "[url]" resulted in a network error response: an object that was not a Response was passed to respondWith().
我是服务人员的新手,因此对于任何错误的术语或不良做法深表歉意,欢迎任何提示。谢谢!
如果不对此进行测试,我的猜测是在没有缓存匹配的情况下您没有正确解析 respondWith()
。 According to MDN,传递给 respondWith()
的代码应该是 "resolve by returning a Response or network error to Fetch." 那么为什么不尝试这样做:
self.addEventListener('fetch', function(event) {
event.respondWith(
fetch(event.request).catch(function() {
return caches.match(event.request);
})
);
});
你为什么不为你的获取事件打开缓存? 我认为service worker的流程是:
打开缓存
检查请求是否与缓存中的答案匹配
那你回答
或(如果答案不在缓存中):
通过网络检查请求
从网络克隆你的答案
将请求和答案的克隆放入缓存中以备将来使用
我会写:
self.addEventListener('fetch', event => {
event.respondWith(
caches.open(CACHE_NAME).then(cache => {
return cache.match(event.request).then(response => {
return response || fetch(event.request)
.then(response => {
const responseClone = response.clone();
cache.put(event.request, responseClone);
})
})
}
);
});
event.respondWith() expects a promise that resolves to Response。因此,如果缓存未命中,您仍然需要 return 一个响应,但在上面,您什么都没有 return。我也会尝试先使用缓存,然后再获取,但无论如何,作为最后的手段,你总是可以创建一个合成的响应,例如这样的东西:
return new Response("Network error happened", {"status" : 408, "headers" : {"Content-Type" : "text/plain"}});