Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
726 views
in Technique[技术] by (71.8m points)

javascript - Service worker offline page won't load

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

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

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)

Any ideas?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Replace your fetch event code with this one. For every request your fetch event will be invoked and it will check if your request is found in the cache file list then it will serve the file from there otherwise it will make the fetch call to get the file from server.

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

Also you don't need a separate "offline.html" file in your cache file list. Instead add your main application html file and your relevant css and js files in that list. That will make your application completely offline in case of no network.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...