Newsletter
TechAnV Blog
Get updates on security engineering, Rust, eBPF, and DevSecOps. No spam, unsubscribe anytime.
Check your inbox and click the confirmation link to complete your subscription.
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:
1<h1>Service worker demo</h1>2
3<script>4const registerServiceWorker = async () => {5 if ('serviceWorker' in navigator) {6 try {7 const registration = await navigator.serviceWorker.register(8 '/sw.js',9 {10 scope: '/',11 }12 );13 if (registration.installing) {14 console.log('Service worker installing');15 } else if (registration.waiting) {16 console.log('Service worker installed');17 } else if (registration.active) {18 console.log('Service worker active');19 }20 } catch (error) {21 console.error(`Registration failed with ${error}`);22 }23 }24};25
26registerServiceWorker();27</script>This is using the service worker registration boilerplate from MDN.
Then my service worker script itself in sw.js just does this:
1self.addEventListener('fetch', (event) => {2 const request = event.request;3 const url = (new URL(request.url));4 if (url.pathname == "/") {5 // Don't intercept hits to the homepage6 return;7 }8 const params = new URLSearchParams(url.search);9 const info = {10 url: request.url,11 method: request.method,12 path: url.pathname,13 params: Array.from(params.entries())14 };15 event.respondWith(new Response(16 `<p>Hello world! Request was: <pre>${JSON.stringify(info, null, 4)}</p>`, {17 headers: { 'Content-Type': 'text/html' }18 }));19});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:
1python3 -m http.server 8009Then 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"
]
]
}](https://user-images.githubusercontent.com/9599/166125219-7820133e-4c9f-4ea2-898b-87b126f07115.png)