skip to Main Content

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.

2

Answers


  1. Chosen as BEST ANSWER

    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;
        },
    };
    

  2. to overide postMessage to all Worker instance create after your script runs, use a Proxy to intercept the Worker constructor and modify the postMessage method on each worker after it’s instantiated:

     const workerTarget = Worker;
        const workerHandler = {
          construct(target, args){
            const workInstance = new target(...args);
            workerInstance.postMessage = function(...messageArgs){
             console.log('Intercepted postMessage:', messageArgs);
            };
            return workerInstance;
          }
        };
       Worker = new Proxy(workerTarget, workerHandler);
    

    this is ensure that postMessage is overridden for all workers created afterwords. make sure the script run before any workers are created on the page.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search