Intercepting fetch in a service worker

I'm learning service workers. I wanted to start with one that intercepts calls to a /path and returns "Hello World".

Here's the initial recipe I came up with.

index.html contained this:

<h1>Service worker demo</h1>

<script>
const registerServiceWorker = async () => {
  if ('serviceWorker' in navigator) {
    try {
      const registration = await navigator.serviceWorker.register(
        '/sw.js',
        {
          scope: '/',
        }
      );
      if (registration.installing) {
        console.log('Service worker installing');
      } else if (registration.waiting) {
        console.log('Service worker installed');
      } else if (registration.active) {
        console.log('Service worker active');
      }
    } catch (error) {
      console.error(`Registration failed with ${error}`);
    }
  }
};

registerServiceWorker();
</script>

This is using the service worker registration boilerplate from MDN.

Then my service worker script itself in sw.js just does this:

self.addEventListener('fetch', (event) => {
  const request = event.request;
  const url = (new URL(request.url));
  if (url.pathname == "/") {
    // Don't intercept hits to the homepage
    return;
  }
  const params = new URLSearchParams(url.search);
  const info = {
    url: request.url,
    method: request.method,
    path: url.pathname,
    params: Array.from(params.entries())
  };
  event.respondWith(new Response(
    `<p>Hello world! Request was: <pre>${JSON.stringify(info, null, 4)}</p>`, {
    headers: { 'Content-Type': 'text/html' }
  }));
});

You have to run service workers with a real web server - you can't serve them directly from disk.

I used the Python 3 one-liner recipe for that:

python3 -m http.server 8009

Then I visited http://localhost:8009/ to load the service worker.

Then I visited http://localhost:8009/foo/bar?a=1&b=2 and got this:

Hello world! Request was: {
"url": "http://localhost:8009/foo/bar?a=1&b=2",
"method": "GET",
"path": "/foo/bar",
"params": [
[
"a",
"1"
],
[
"b",
"2"
]
]
}

Created 2022-04-30T15:56:28-07:00 · Edit