简体   繁体   中英

How to make a service worker work offline?

I can't get my service worker to work offline. No matter what tutorial I use.

I registered the service worker in my index.html file like:

<script>
    if ('serviceWorker' in navigator) {
        window.addEventListener('load', () => {
            navigator.serviceWorker.register('/serviceworker.js')
                .then((reg) => console.log('success: ', reg.scope))
                .catch((err) => console.log('Failure: ', err))
        })
    }
</script>

The serviceworker.js looks like:

const CACHE_NAME = "version-1"
const urlsToCache = [ 'index.html' ]

const self = this

// Install Service Worker
self.addEventListener('install', (event) => {
    event.waitUntil(
        caches.open(CACHE_NAME)
            .then((cache) => {
                console.log('Opened cache')

                return cache.addAll(urlsToCache)
            })
    )
})
// Activate Service Worker
self.addEventListener('activate', (event) => {
    const cacheWhitelist = []
    cacheWhitelist.push(CACHE_NAME)

    event.waitUntil(
        caches.keys().then((cacheNames) => Promise.all(
            cacheNames.map((cacheName) => {
                if(!cacheWhitelist.includes(cacheName)) {
                    return caches.delete(cacheName)
                }
            })
        ))

    )
})

I'm not sure what I've forgotten or what mistake I have. The serviceworker.js is right beside the index.html, manifest.json etc.

I sometimes get an error with "An unknown error occured when fetching the script".

Kind regards

Your service worker only contains code to create a cache and store the HTML file in that local cache. This cache is managed by you, the browser does not care about it when fetching web pages normally.

When your browser fetches that index.html web page, it does not know about that cache. So what you need to do is to intercept that fetch. For this, you need to register an event listener for the fetch event and respond with your cache. The browser will then use that file instead of sending a request to the server.

self.addEventListener('fetch', event => { 
  if (event.request.method != 'GET') return;
  event.respondWith(async function() {
    const cache = await caches.open(CACHE_NAME);
    const cached = await cache.match(event.request);
    // If no cached version, fall back to server fetch
    return cached ? cached : fetch(event.request);
  })
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM