https://developer.mozilla.org/en/docs/Web/API/Service_Worker_API
Service workers essentially act as proxy servers that sit between web applications, and the browser and network (when available).
It takes the form of a JavaScript file that can control the web page/site it is associated with, intercepting and modifying navigation and resource requests
You register a service worker in your application code from a file named, e.g., sw.js
by doing:
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('sw.js').then(function(registration) {
console.log('Service worker registered with scope: ', registration.scope);
}, function(err) {
console.log('ServiceWorker registration failed: ', err);
});
});
}
And in the sw.js
file (the actual service-worker code): To intercept requests, you attach a fetch
event listener to the service worker that calls the respondWith()
method and does something with the .request
member from the event object:
self.addEventListener('fetch', function(event) {
event.respondWith(
// intercept requests by handling event.request here
);
});
A simple service worker that just passes through requests unchanged looks like this:
self.addEventListener('fetch', function(event) {
event.respondWith(
fetch(event.request)
);
});
To add a param to the request body, you need to:
- Serialize the request.
- Modify that serialized request.
- Deserialize the modified request to create a new request.
- Call
fetch(…)
with that new request.
So, a service worker that does all that would look like this (untested):
self.addEventListener('fetch', function(event) {
event.respondWith(
fetchWithParamAddedToRequestBody(event.request)
);
});
function fetchWithParamAddedToRequestBody(request) {
serialize(request).then(function(serialized) {
// modify serialized.body here to add your request parameter
deserialize(serialized).then(function(request) {
return fetch(request);
});
}); // fixed this
}
function serialize(request) {
var headers = {};
for (var entry of request.headers.entries()) {
headers[entry[0]] = entry[1];
}
var serialized = {
url: request.url,
headers: headers,
method: request.method,
mode: request.mode,
credentials: request.credentials,
cache: request.cache,
redirect: request.redirect,
referrer: request.referrer
};
if (request.method !== 'GET' && request.method !== 'HEAD') {
return request.clone().text().then(function(body) {
serialized.body = body;
return Promise.resolve(serialized);
});
}
return Promise.resolve(serialized);
}
function deserialize(data) {
return Promise.resolve(new Request(data.url, data));
}
Note: https://serviceworke.rs/request-deferrer_service-worker_doc.html, a page from the Service Worker Cookbook, is where I lifted that serialize(…)
code/approach from—by way of the answer at https://stackoverflow.com/questions/35420980/how-to-alter-the-headers-of-a-request/35421644#35421644—and it’s worth taking a look at, because the code there has detailed annotations explaining what it’s all doing