Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SERVICE WORKER: The service worker navigation preload request failed with network error: net::ERR_INTERNET_DISCONNECTED in Chrome 89

I have a problem with my Service Worker.

I'm currently implementing offline functionality with an offline.html site to be shown in case of network failure. I have implemented Navigation Preloads as described here: https://developers.google.com/web/updates/2017/02/navigation-preload#activating_navigation_preload

Here is my install EventListener were skipWaiting() and initialize new cache

const version = 'v.1.2.3'
const CACHE_NAME = '::static-cache'
const urlsToCache = ['index~offline.html', 'favicon-512.png']

self.addEventListener('install', function(event) {
    self.skipWaiting()
    event.waitUntil(
        caches
            .open(version + CACHE_NAME)
            .then(function(cache) {
                return cache.addAll(urlsToCache)
            })
            .then(function() {
                console.log('WORKER: install completed')
            })
    )
})

Here is my activate EventListener were I feature-detect navigationPreload and enable it. Afterwards I check for old caches and delete them

self.addEventListener('activate', event => {
    console.log('WORKER: activated')
    event.waitUntil(
        (async function() {
            // Feature-detect
            if (self.registration.navigationPreload) {
                // Enable navigation preloads!
                console.log('WORKER: Enable navigation preloads')
                await self.registration.navigationPreload.enable()
            }
        })().then(
            caches.keys().then(function(cacheNames) {
                cacheNames.forEach(function(cacheName) {
                    if (cacheName !== version + CACHE_NAME) {
                        caches.delete(cacheName)
                        console.log(cacheName + ' CACHE deleted')
                    }
                })
            })
        )
    )
})

This is my fetch eventListener

self.addEventListener('fetch', event => {
    const { request } = event

    // Always bypass for range requests, due to browser bugs
    if (request.headers.has('range')) return
    event.respondWith(
        (async function() {
            // Try to get from the cache:
            const cachedResponse = await caches.match(request)
            if (cachedResponse) return cachedResponse

            try {
                const response = await event.preloadResponse
                if (response) return response

                // Otherwise, get from the network
                return await fetch(request)
            } catch (err) {
                // If this was a navigation, show the offline page:
                if (request.mode === 'navigate') {
                    console.log('Err: ',err)
                    console.log('Request: ', request)
                    return caches.match('index~offline.html')
                }

                // Otherwise throw
                throw err
            }
        })()
    )
})

Now my Problem: On my local machine on localhost everything just works as it should. If network is offline the index~offline.html page is delivered to the user. If I deploy to my test server everything works as well as expected, except for a strange error-message in Chrome on normal browsing(not offline mode):

The service worker navigation preload request failed with network error: net::ERR_INTERNET_DISCONNECTED.

I logged the error and the request to get more information Error:

DOMException: The service worker navigation preload request failed with a network error.

Request: Request

Its strange because somehow index.html is requested no matter which site is loaded.

Additional Information this is happening in Chrome 89, in chrome 88 everything seems fine(I checked in browserstack). I just saw there was a change in pwa offline detection in Chrome 89... https://developer.chrome.com/blog/improved-pwa-offline-detection/

anybody has an idea what the problem might be?

Update I rebuild the problem here so everybody can check it out: https://dreamy-leavitt-bd4f0e.netlify.app/

like image 850
veduardo Avatar asked Mar 26 '21 14:03

veduardo


1 Answers

This error is directly caused by the improved pwa offline detection you linked to: https://developer.chrome.com/blog/improved-pwa-offline-detection/

The browser fakes an offline context and tries to request the start_url of your manifest, e.g. the index.html specified in your https://dreamy-leavitt-bd4f0e.netlify.app/site.webmanifest

This is to make sure that your service worker is actually returning a valid 200 response in this situation, i.e. the valid cached response for your index~offline.html page.

The error you're asking about specifically is from the await event.preloadResponse part and it apparently can't be suppressed.

The await fetch call produces a similar error but that can be suppressed, just don't console.log in the catch section.

Hopefully chrome won't show this error from preload responses in future when doing offline pwa detection as it's needlessly confusing.

like image 151
James Wheare Avatar answered Oct 08 '22 14:10

James Wheare