I want to override the postMessage() function in all Worker created after the override. I am doing this in a browser extension from a content script before page is loaded.
I have tried to simply override it like this:
Worker.prototype.postMessage = function() {
console.log('post1:');
};
Worker.postMessage = function() {
console.log('post2');
};
But this does nothing.
I also tried proxying the object creation like this:
const workerTarget = Worker;
const workerHandler = {
construct(target, args) {
console.log(`Creating a ${target.name}`);
console.log('args:' + args);
var t = new workerTarget(args);
return t;
},
};
const workerProxy = new Proxy(workerTarget, workerHandler);
Worker = workerProxy;
This seems to work since I get the console log entries and the worker is not messed up, i.e. it still does it's job.
But if I try to override postMessage() after the Worker is constructed like this:
const workerTarget = Worker;
const workerHandler = {
construct(target, args) {
console.log(`Creating a ${target.name}`);
console.log('args:' + args);
var t = new workerTarget(args);
t.postMessage = function(...args2) {
console.log('post');
};
return t;
},
};
const workerProxy = new Proxy(workerTarget, workerHandler);
Worker = workerProxy;
It does not work, nothing happens to the Worker.
EDIT I tried another approach, using the onmessage property instead, which should let me inspect any message posted by any worker thread to the main script?
const onmessagegetter = Object.getOwnPropertyDescriptor(Worker.prototype, 'onmessage').get;
const onmessagesetter = Object.getOwnPropertyDescriptor(Worker.prototype, 'onmessage').set;
Object.defineProperty(Worker.prototype, 'onmessage', {
get() {
console.log('getCalled');
return onmessagegetter.apply(this);
},
set() {
console.log('setCalled');
return onmessagesetter.apply(this, arguments);
}
});
Will this let me inspect all messages posted by any worker? (dedicated/shared/service)
EDIT2 Looks like this will only let me see when the onmessage() is declared not when the event is triggered.
So I still do not know exactly why you cannot override postMessage, so if anyone can give a good explanation please comment.
I resolved my problem with another approach, pre appending my own script to the Worker script at creation like this:
const workerHandler = {
construct(target, args) {
console.log(`Creating a ${target.name}`);
console.log('args:' + args);
const request = new XMLHttpRequest();
request.open("GET", args, false); // `false` makes the request synchronous
request.send(); // blocks until response
if (request.status === 200) {
console.log('XHR Success');
}
else{
console.log('XHR Failed');
}
const sourceBlob = new Blob([request.responseText]);
const blob = new Blob([ '(' + payload.toString() + ')();' , sourceBlob ], {type: 'application/javascript'});
const t = new target(URL.createObjectURL(blob));
return t;
},
};