服务人员离线页面无法加载 [英] Service worker offline page won't load

查看:55
本文介绍了服务人员离线页面无法加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这曾经对我有用,但是在几个月前就停止了,我已经重新定位了自己,无法再解决这个问题了.我在这里做什么错了?

This used to work for me but stopped a couple of months ago and I've tinkered my way right out of being able to figure this out anymore. What am I doing wrong here?

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

Call the service worker template, no problem:

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.');
}

设置缓存版本并预加载缓存,没问题:

Setup a cache version and preloaded the cache, no problem:

const cacheName='2020.10.06-01';

var cacheFiles = ['/offline.html'];

安装了服务工作者,没问题:

Installed the Services Worker, no problem:

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

激活Services Worker进行自动缓存过渡,没问题:

Activated the Services Worker for auto cache rollover, no problem:

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

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

Fetching from cache or network, no problem:

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"页面.(我知道缓存中有IS)

But if the page/resource I'm trying to request is not already in the cache AND the network is not available it refuses to display my 'offline.html' page. (Which I know IS in the cache)

有什么想法吗?

推荐答案

这是我最后编写的对我来说非常合适的Fetch代码:

Here's the Fetch code I wrote in the end that works perfectly for me:

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;
    }
  })());
});

这按特定顺序完成了我需要的所有操作.它首先检查缓存,如果找到则将其返回.下一步检查网络,如果发现,则先对其进行缓存,然后将其返回.或者,它会显示一个自定义的离线页面,并带有一个较大的重新加载"按钮,以鼓励访问者重返在线后再试一次.

This does everything I need, in a very specific order. It checks the cache first, if found it's returned. It checks the network next, if found it caches it first then returns it. Or it displays a custom offline page with a big Reload button to encourage visitors to try again when they are back online.

但是要意识到的最重要的一点是,以这种方式进行操作可以使我显示一个页面及其所有资源(无论是否具有网络访问权限).

But the most important this to realise is that doing it this way alows me to display a page and all it's resources with or without network access.

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

UPDATE: In order to deal with changes to CORS security requirements that where implemented in all browsers between March and August of 2020, I had to make one small change to the 'fetch' event.

更改自:

const fetchResponse = await fetch(event.request);

收件人:

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

这篇关于服务人员离线页面无法加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆