GoogleChrome / samples

A repo containing samples tied to new functionality in each release of Google Chrome.
https://www.chromestatus.com/samples
Apache License 2.0
5.79k stars 2.38k forks source link

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

Closed sanishkr closed 4 years ago

sanishkr commented 4 years ago

Regarding: Service Worker Sample: Custom Offline Page Sample demo link github link

I followed the same process as in demo above. The offline page is available in the cache as well. But when I switch off my network or check offline in Application/Service Workers tab, it gives DOMException: The service worker navigation preload request failed with a network error. and the screen says "This site can't be reached". At this time, the SW cache storage does not appear to have anything. The items in the cache appear back as soon as I go online. I am running my nextJS server on localhost:3000 and using workbox.

Any help is appreciated.

jeffposnick commented 4 years ago

If you're using Workbox, then that sample isn't really applicable. The code there is for a "vanilla" service worker that doesn't use any libraries.

If you're having trouble with your Workbox config, could you open an issue at https://github.com/GoogleChrome/workbox/issues/new with details, including the contents of your service worker file?

sanishkr commented 4 years ago

@jeffposnick , thanks for quick response. It will be great if you can try to understand the issue before quickly closing it.

Workbox is a tool which builds sw only. And there is a way to import any other vanilla js (like the one in above repo) in the workbox using importScripts(). All event listeners from above example are being called in my code as well, offline page is cached too. Only thing is fetch event listener is not working as expected when going offline.

here is the build output of my sw., if it helps. service-worker.js

self.__precacheManifest = [
  {
    "url": "/_next/static/chunks/commons.96032d0a294fdcddc8ea.js",
    "revision": "7160ef3b63c57fa8a8fd"
  },
  {
    "url": "/_next/static/chunks/styles.65398a7ba973f8e2fc10.js",
    "revision": "17cad05ac454bc9be863"
  },
.
. more routes like this
.

  {
    "url": "/_next/static/runtime/main-03c90aacd405ae2c4800.js",
    "revision": "3b604b35772553e4daa9"
  },
  {
    "url": "/_next/static/runtime/webpack-4b444dab214c6491079c.js",
    "revision": "71726f334912f74c262a"
  }
];

/**
 * Welcome to your Workbox-powered service worker!
 *
 * You'll need to register this file in your web app and you should
 * disable HTTP caching for this file too.
 * See https://goo.gl/nhQhGp
 *
 * The rest of the code is auto-generated. Please don't update this file
 * directly; instead, make changes to your Workbox build configuration
 * and re-run your build process.
 * See https://goo.gl/2aRDsh
 */

importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");

importScripts(
  "sw-window.js"
);

self.addEventListener('message', (event) => {
  if (event.data && event.data.type === 'SKIP_WAITING') {
    self.skipWaiting();
  }
});

/**
 * The workboxSW.precacheAndRoute() method efficiently caches and responds to
 * requests for URLs in the manifest.
 * See https://goo.gl/S9QRab
 */
self.__precacheManifest = [].concat(self.__precacheManifest || []);
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});

.
.
some other private routing strategies for images/css/etc..
.
.
workbox.routing.registerRoute(/\//, new workbox.strategies.NetworkFirst({ "cacheName":"https-calls","networkTimeoutSeconds":15, plugins: [new workbox.expiration.Plugin({ maxEntries: 150, maxAgeSeconds: 2592000, purgeOnQuotaError: false }), new workbox.cacheableResponse.Plugin({ statuses: [ 0, 200 ] })] }), 'GET');

sw-window.js

console.log("workbox window...");

const OFFLINE_VERSION = 1;
const CACHE_NAME = 'offline';
const OFFLINE_URL = '/offline.html';

self.addEventListener('install', (event) => {
  console.log({event},'install');
  if (event.data && event.data.type === 'SKIP_WAITING') {
    self.skipWaiting();
  }
  event.waitUntil((async () => {
    const cache = await caches.open(CACHE_NAME);
    await cache.add(new Request(OFFLINE_URL, {cache: 'reload'}));
  })());
});

self.addEventListener('activate', (event) => {
  console.log({event},'activate');
  event.waitUntil((async () => {
    if ('navigationPreload' in self.registration) {
      await self.registration.navigationPreload.enable();
    }
  })());
  self.clients.claim();
});

self.addEventListener('fetch', (event) => {
  if (event.request.mode === 'navigate') {
    event.respondWith((async () => {
      try {
        console.log("fetch",{event});

        const preloadResponse = await event.preloadResponse;
        if (preloadResponse) {
          return preloadResponse;
        }
        const networkResponse = await fetch(event.request);
        return networkResponse;
      } catch (error) {
        console.log('Fetch failed; returning offline page instead.', error);
        const cache = await caches.open(CACHE_NAME);
        const cachedResponse = await cache.match(OFFLINE_URL);
        return cachedResponse;
      }
    })());
  }
});