服务工作进程脱机页面无法加载



这曾经对我有效,但几个月前就停止了,我已经修正了自己的方法,无法再解决这个问题。我在这里做错了什么?

调用服务工作者模板,没有问题:

if(navigator.serviceWorker){
window.addEventListener('load',() => {
navigator.serviceWorker
.register('/sw.js')
.then(console.log('[ServiceWorker] Registered Successfully'))
.catch(err => console.log(`[ServiceWorker] Error: ${err}`));
});
} else {
console.log('Service Worker not supported.');
}

设置缓存版本并预装缓存,没有问题:

const cacheName='2020.10.06-01';
var cacheFiles = ['/offline.html'];

已安装Services Worker,没有问题:

addEventListener('install', e => {
e.waitUntil(
caches.open(cacheName).then(cache => {
return cache.addAll(cacheFiles);
})
);
});

激活服务工作程序进行自动缓存滚动,没有问题:

addEventListener('activate', e => {
e.waitUntil(
caches.keys().then(keyList => {
return Promise.all(keyList.map(key => {
if(key !== cacheName) {
return caches.delete(key);
}
}));
})
);
});

从缓存或网络获取,没有问题:

addEventListener('fetch', e => {
e.respondWith(async function() {
try {
const cache = await caches.open(cacheName);
const cachedResponse = await cache.match(e.request);
const networkResponsePromise = fetch(e.request);
e.waitUntil(async function() {
const networkResponse = await networkResponsePromise;
await cache.put(e.request, networkResponse.clone());
}());
// Returned the cached response if we have one, otherwise return the network response.
return cachedResponse || networkResponsePromise;
} catch (error) {
console.log('Fetch failed; returning offline page instead.', error);
const cache = await caches.open(cacheName);
const cachedResponse = await cache.match('/offline.html');
return cachedResponse;
}
}());
});

但是,如果我试图请求的页面/资源尚未在缓存中,并且网络不可用,它将拒绝显示我的"offline.html"页面。(我知道它在缓存中(

有什么想法吗?

这是我最后写的Fetch代码,非常适合我:

self.addEventListener('fetch', (event) => {
event.respondWith((async() => {
const cache = await caches.open(cacheName);
try {
const cachedResponse = await cache.match(event.request);
if(cachedResponse) {
console.log('cachedResponse: ', event.request.url);
return cachedResponse;
}
const fetchResponse = await fetch(event.request);
if(fetchResponse) {
console.log('fetchResponse: ', event.request.url);
await cache.put(event.request, fetchResponse.clone());
return fetchResponse;
}
}   catch (error) {
console.log('Fetch failed: ', error);
const cachedResponse = await cache.match('/en/offline.html');
return cachedResponse;
}
})());
});

这做了我需要的一切,按照一个非常具体的顺序。它首先检查缓存,如果找到,就会返回。它接下来会检查网络,如果发现,它会先缓存然后返回。或者,它会显示一个带有"重新加载"大按钮的自定义脱机页面,鼓励访问者在重新联机时重试。

但最重要的是,这样做可以让我在有或没有网络访问的情况下显示页面及其所有资源。

更新:为了应对2020年3月至8月期间在所有浏览器中实现的CORS安全要求的更改,我不得不对"fetch"事件进行一个小更改。

更改自:

const fetchResponse = await fetch(event.request);

收件人:

const fetchResponse = await fetch(event.request, {mode:'no-cors'});

用这个代码替换获取事件代码。对于每个请求,您的fetch事件都会被调用,它会检查您的请求是否在缓存文件列表中找到,然后它会从那里提供文件,否则它会调用fetch从服务器获取文件。

self.addEventListener("fetch", function (event) {
event.respondWith(
caches.match(event.request)
.then(function (response) {
if (response) {
return response;
}
return fetch(event.request);
})
);
});

此外,您不需要单独的";offline.html";缓存文件列表中的文件。相反,在该列表中添加您的主应用程序html文件以及相关的css和js文件。这将使您的应用程序在没有网络的情况下完全离线。

最新更新