Search code examples
javascriptservice-workeroffline-caching

Detecting online status when using service worker does not work


I'm using google workbox to make some content offline available with service workers. The offline part works as intended. But I'd like to give the user a message (fe. with a popup or) when the client has network access again. I tried to achieve that with the online event listener of the browser. I opened the page with chrome, then i put chrome into the offline mode. After that I navigate to index2.htm and the offline content is displayed (=works). Then i put chrome into the online mode again, but the online-event doesn't get triggered. Does anybody knows why and how to fix that?

My files:

sw.js

importScripts('https://storage.googleapis.com/workbox-cdn/releases/5.0.0/workbox-sw.js');
if (workbox) {
    precaching.precacheAndRoute([{
        url: 'https://playground.test/index2.htm',
        revision: 1
    }]);
    self.addEventListener('fetch', (event) => {
        fetch(event.request)
            .catch(function (e) {
                return caches.match(event.request);
            });
    });
}

index.htm

<!DOCTYPE html>
<html>
<head>
    <title>Page 1</title>
</head>
<body>
    <a href="index2.htm">Index2</a>
    <script>
        if ('serviceWorker' in navigator) {
            window.addEventListener('load', () => {
                navigator.serviceWorker.register('/sw.js');
            });
        }
    </script>
</body>
</html>

index2.htm

<!DOCTYPE html>
<html>
<head>
    <title>Page 2</title>
    <script src="offline.js"></script>
</head>
<body>
    <h1>Page 2</h1>
</body>
</html>

offline.js

window.addEventListener('load', () => {
    const handleNetworkChange = () => {
        if (navigator.onLine) {
            alert('You are online again!');
        }
    };
    window.addEventListener('online', handleNetworkChange);
});

Solution

  • I have the same problem and I resolve this with this code:

      const hasInternet = (url = 'https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png?x=' + Math.random()): Promise<boolean> => {
    return new Promise(resolve => {
    
      let img = new Image();
      img.onload = function () { resolve(true); };
      img.onerror = function () { resolve(true); };
    
      img.src = url;
      setTimeout(function () { resolve(false); }, 5000);
    });
    }