Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Caching a link to another page with service worker

I am looking to cache the contents of a dynamic linked page. I have a simple index.html with a service worker registered, and want to set it up where when you reach this page it dynamically caches the contents that the link is pointing to (the idea is that this second page will not be included in the static install event).

Basically I am designing a page that will have a link to a recommended/related page which I want to be stored in the cache. When the user clicks the link to the recommended related page I want it to load from the cache.

index.html:

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="style.css">
    <script src="script.js"></script>
  </head>
  <body>
    <h1>Hello Plunker!</h1>
    <h3>I want to cache</h3>
    <a href="page2.html">this link to my second page!</a> 
  <script>
    if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register('/sw.js').then(function(reg) {
        // registration worked
        console.log('Registration succeeded. Scope is ' + reg.scope);
      }).catch(function(error) {
        // registration failed
        console.log('Registration failed with ' + error);
      });
    }
  </script>
  </body>    
</html>

page2.html:

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="style.css">
    <script src="script2.js"></script>
  </head>
  <body>
    <h1>This is my second page!</h1>
    <h3>I want everything from this page to be stored in the cache.</h3>
  </body> 
</html>

Here is the plunkr: https://plnkr.co/edit/YIAacgkuboyRBkv10hfl?p=catalogue

How can I set up my fetch event to dynamically cache the contents of the second page without explicitly putting page2.html in my static install event?

like image 246
Jess Anastasio Avatar asked Oct 30 '22 00:10

Jess Anastasio


1 Answers

According to your updated question, you could do it with the Client.postMessage().

In your client/html/script

<a href="/url/cache-this" class="precache"></a>
<script>
if ('serviceWorker' in navigator) {

  // ensure service worker is ready, you can also put this into DOM 'ready' or 'load' event
  navigator.serviceWorker.ready.then(function (reg) {

    var data = {
      action: "precache", 
      url: $('.precache').attr('href') // if you had more than an url need to be cached, do a loop to collect all data
    };
    // NOTE: the 'action' is optional, but it is nice to separate your message type, in case you have a lot of communication between DOM and service worker.

    // message to SW a stringified string of data.
    navigator.serviceWorker.controller.postMessage(JSON.stringify(data));

  });
}
</script>

In your service worker.

self.addEventListener('message', event => {

  if (event.data) { 
    let data = JSON.parse(event.data); // parse the message back to JSON
    if (data.action == "precache") { // check the action
        self.toolbox.precache([data.url]); // here you can use sw-toolbox or anything to cache your stuff.
    }
  }
});

EDIT: fixed typos

like image 146
Linh Pham Avatar answered Nov 11 '22 03:11

Linh Pham