web-dev-qa-db-fra.com

Meilleures pratiques pour détecter l'état hors ligne dans un travailleur de service

J'ai un technicien qui est censé mettre en cache un offline.html page qui s'affiche si le client n'a pas de connexion réseau. Cependant, il pense parfois que le navigateur est hors ligne, même s'il ne l'est pas. C'est, navigator.onLine === false. Cela signifie que l'utilisateur peut obtenir offline.html au lieu du contenu proprement dit, même en ligne, ce que j'aimerais évidemment éviter.

Voici comment j'enregistre le technicien dans mon main.js:

// Install service worker for offline use and caching
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/service-worker.js', {scope: '/'});
}

Mon actuel service-worker.js:

const OFFLINE_URL = '/mysite/offline';
const CACHE_NAME = 'mysite-static-v1';

self.addEventListener('install', (event) => {
  event.waitUntil(
    // Cache the offline page when installing the service worker
    fetch(OFFLINE_URL, { credentials: 'include' }).then(response =>
      caches.open(CACHE_NAME).then(cache => cache.put(OFFLINE_URL, response)),
    ),
  );
});

self.addEventListener('fetch', (event) => {
  const requestURL = new URL(event.request.url);

  if (requestURL.Origin === location.Origin) {
    // Load static assets from cache if network is down
    if (/\.(css|js|woff|woff2|ttf|eot|svg)$/.test(requestURL.pathname)) {
      event.respondWith(
        caches.open(CACHE_NAME).then(cache =>
          caches.match(event.request).then((result) => {
            if (navigator.onLine === false) {
              // We are offline so return the cached version immediately, null or not.
              return result;
            }
            // We are online so let's run the request to make sure our content
            // is up-to-date.
            return fetch(event.request).then((response) => {
              // Save the result to cache for later use.
              cache.put(event.request, response.clone());
              return response;
            });
          }),
        ),
      );
      return;
    }
  }

  if (event.request.mode === 'navigate' && navigator.onLine === false) {
    // Uh-oh, we navigated to a page while offline. Let's show our default page.
    event.respondWith(caches.match(OFFLINE_URL));
    return;
  }

  // Passthrough for everything else
  event.respondWith(fetch(event.request));
});

Qu'est-ce que je fais mal?

16
Kaivosukeltaja

navigator.onLine Et les événements associés peuvent être utiles lorsque vous souhaitez mettre à jour votre interface utilisateur pour indiquer que vous êtes hors ligne et, par exemple, n'afficher que le contenu qui existe dans un cache.

Mais j'éviterais d'écrire une logique de service worker qui repose sur la vérification de navigator.onLine. Au lieu de cela, essayez de créer une fetch() sans condition, et si elle échoue, fournissez une réponse de sauvegarde. Cela garantira que votre application Web se comporte comme prévu, que la fetch() échoue en raison de sa déconnexion, de lie-fi ou de problèmes de serveur Web.

// Other fetch handler code...

if (event.request.mode === 'navigate') {
  return event.respondWith(
    fetch(event.request).catch(() => caches.match(OFFLINE_URL))
  );
}

// Other fetch handler code...
13
Jeff Posnick