I’m trying to intercept and modify POST requests to an API made by a website.
I know this can be done by monkeypatching XMLHttpRequest() and fetch() however it turns out that the request is done by a worker (confirmed it with Worker() = "";
) so the above methods don’t affect it.
And you can’t monkeypatch Worker()
as far as I know.
So I tried registering my own worker that will intercept the requests from a string resulting in the following code:
var script = document.createElement("script");
script.id = "worker1";
script.innerHTML = `
var b = "";
self.onmessage = function(e) {
b = self.fetch;
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));
};
self.postMessage("hello world");
};
`;
document.head.prepend(script);
var blob = new Blob([document.querySelector('#worker1').textContent], {type:"text/javascript"});
var worker = new Worker(window.URL.createObjectURL(blob));
worker.onmessage = function (e){
console.log("Received: "+e.data);
};
worker.postMessage("hello");```
However I don't really know what I'm doing so this is probably wrong.
Besides I suspect this method will only allow me to intercept requests from the document and not from other workers...
Would replacing the real worker with my worker allow me to monkeypatch the requests APIs for it?
But when I try posting a message with `self.fetch` from inside a worker (`worker.postMessage(b);`) it tells me the function is native code unlike in `window`, which suggests this is not so simple...
I also saw [this topic](/questions/54902877/javascript-intercept-http-fetch-from-web-worker-file-urls), however it seems that it doesn't have a working answer and it uses `navigator.serviceWorker.register()` from file, and I'm not sure how that works with a Blob.
Can this be done at all?
Archimedes5000 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.