0

Simply, I'm trying to make simple functionality for my web app when the browser being in the offline. The functionality is a simple message that tells the user about there is no network connectivity instead of the default's browser's page. I have tried the following:

window.addEventListener("beforeunload", function() {
                if (!navigator.onLine){
                    document.write("There is no network connection."); debugger;return false; 
                }                 
                }, false);

The above code worked with Chrome, but it does not work with firefox. I have two questions here:

  1. How could I make this cross-browsers?
  2. Is there any other way than using debugger?

Update

The answer of this question should be an implementation of

SaidbakR
  • 13,303
  • 20
  • 101
  • 195

1 Answers1

1

Finally I found how to implement simple service worker for my website. The final result appears in the following screen shot:

enter image description here

After disconnecting the client's machine from the network, (Not use browser's development tools offline) and making the following steps, the offline.html is loaded for every website's page.

  1. I used an online tool that generates required service code, PWA Builder, I escaped the first step there, Generate Manifest, I started directly with step 2, Build Service Worker. I copied code for website from there, but I have modified some paths to point to the server's root because the code is going to be pasted in application layout, like the following:

    // In the most top part of the layout HTML //This is the "Offline page" service worker

    //Add this below content to your HTML page, or add the js file to your page at the very top to register sercie worker
    if (navigator.serviceWorker.controller) {
      console.log('[PWA Builder] active service worker found, no need to register')
    } else {
      //Register the ServiceWorker
      navigator.serviceWorker.register('/pwabuilder-sw.js', { //notice slash in /pwabuilder-sw.js
        scope: './'
      }).then(function(reg) {
        console.log('Service worker has been registered for scope:'+ reg.scope);
      });
    }
    
    
    </script>
    

    2- I copied the code of Service worker code and saved it a new file in the web root of my application /public as pwabuilder-sw.js with also changing some paths with slashes:

    //This is the "Offline page" service worker

    //Install stage sets up the offline page in the cahche and opens a new cache
    self.addEventListener('install', function(event) {
      var offlinePage = new Request('/offline.html'); //notice /
      event.waitUntil(
      fetch(offlinePage).then(function(response) {
        return caches.open('pwabuilder-offline').then(function(cache) {
          console.log('[PWA Builder] Cached offline page during Install'+ response.url);
          return cache.put(offlinePage, response);
        });
      }));
    });
    
    //If any fetch fails, it will show the offline page.
    //Maybe this should be limited to HTML documents?
    self.addEventListener('fetch', function(event) {
      event.respondWith(
        fetch(event.request).catch(function(error) {
            console.error( '[PWA Builder] Network request Failed. Serving offline page ' + error );
            return caches.open('pwabuilder-offline').then(function(cache) {
              return cache.match('/offline.html'); //notice /
          });
        }));
    });
    
    //This is a event that can be fired from your page to tell the SW to update the offline page
    self.addEventListener('refreshOffline', function(response) {
      return caches.open('pwabuilder-offline').then(function(cache) {
        console.log('[PWA Builder] Offline page updated from refreshOffline event: '+ response.url);
        return cache.put(offlinePage, response);
      });
    });
    

Finally, I have created public/offline.html file with the following code:

<html>
 <head>
 <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>OffLine</title>
  <style>
   body{
    text-align: center;
    padding: 1em;
    font-family: sans-serif;
    font-size: 30px;
    }
  </style>
 </head>
 <body>
  <img src="data:image/png;base64,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" alt="Disconnected" />
  <h1>OffLine</h1>
  <p>There is no network connectivity.</p>
  <a href="javascript:location.reload()">Click here<a/> to reload after connecting.
 </body>
</html>

Notice

For better results in testing this you may use the following hints:

  1. Clear your browser's cache and restart it.
  2. Disconnect the machine physically, ex: turn off the WiFi, After loading the website for the first time of course!

Additionally

I use jQuery to maintain some ajax requests all over the application, so in the layout script section, I used the following snippet that detect every ajax request before sending it and check if the browser is offline, so it stop the ajax request and alert a message then reload the page to load offline.html:

$( document ).ajaxSend(function(evt) {
    if (!navigator.onLine){
        evt.preventDefault();
        swal({
            title: '{{__('OffLine Error')}}',
            text: '{{__('The browser is offline. Some requests could not be done')}}',
            confirmButtonText: '<i class="fox-finalize"></i>{{__('OK')}}',
            onClose: function(){
                location.reload();
            }
        })
    }
  });  
SaidbakR
  • 13,303
  • 20
  • 101
  • 195