Is it possible to construct a Web Worker from an injected content script?

2,297 views
Skip to first unread message

Sean Anderson

unread,
Jan 13, 2014, 1:57:56 AM1/13/14
to chromium-...@chromium.org
Hey guys,

I'm trying to create a WebWorker from inside of an injected content script, but I'm encountering a security error. Here's what I've got:

"content_scripts": [
{
"matches": ["*://*.youtube.com/embed/*"],
"all_frames": true,
"js": ["js/inject/youTubeIFrameInject.js"]
}
        ]

and inside of my script:

        var worker = new Worker("data:text/javascript;charset=US-ASCII,onmessage%20%3D%20function%20%28oEvent%29%20%7B%0A%09postMessage%28%7B%0A%09%09%22id%22%3A%20oEvent.data.id%2C%0A%09%09%22evaluated%22%3A%20eval%28oEvent.data.code%29%0A%09%7D%29%3B%0A%7D");
        
        worker.onmessage = function (oEvent) {
            console.log("Worker said : " + oEvent.data);
        };

        worker.postMessage("ali");


I receive the error: "Uncaught SecurityError: Failed to create a worker: script at 'data:text/javascript;charset=US-ASCII,onmessage%20%3D%20function%20%28oEven…%09%09%22evaluated%22%3A%20eval%28oEvent.data.code%29%0A%09%7D%29%3B%0A%7D' cannot be accessed from origin 'https://www.youtube.com'. "

My end goal is to leverage the TransferableObject interface when passing messages out of the injected content script: http://updates.html5rocks.com/2011/12/Transferable-Objects-Lightning-Fast

Is this possible? Should it be possible?

Thanks

Sean Anderson

unread,
Jan 13, 2014, 2:02:49 AM1/13/14
to chromium-...@chromium.org
Wait. I am an idiot. It's an inline script which isn't allowed, but I think I can inject another script and then reference it.

Sean Anderson

unread,
Jan 13, 2014, 2:11:20 AM1/13/14
to chromium-...@chromium.org
Oh, nope. Can't do that either, the injected script isn't able to be referenced like that -- it is just executed upon injection.

Sean Anderson

unread,
Jan 13, 2014, 2:21:35 AM1/13/14
to chromium-...@chromium.org
Got it!

        var s = document.createElement("script");
        s.type = "text/js-worker";
        s.innerHTML = 'console.log("i ran!");';
        document.body.appendChild(s);
        
        var blob = new Blob(Array.prototype.map.call(document.querySelectorAll("script[type=\"text\/js-worker\"]"), function (oScript) {
            return oScript.textContent;
        }), { type: "text/javascript" });
        
        var worker = new Worker(window.URL.createObjectURL(blob));
       
        worker.onmessage = function (oEvent) {
            console.log("Called back by the worker!\n");
        };

Rob Wu

unread,
Jan 13, 2014, 9:10:23 AM1/13/14
to chromium-...@chromium.org
You don't need an intermediate <script> tag to create a worker from a string.
See http://stackoverflow.com/questions/10343913/how-to-create-a-web-worker-from-a-string for a cross-browser way of creating Workers from strings.

Since you're writing a Chrome extension for modern Chrome browsers, you can simplify the code to

var response = "self.onmessage=function(e){postMessage('Worker: ' + e.data);}";
var blob = new Blob([response], {type: 'application/javascript'});
var worker = new Worker(URL.createObjectURL(blob));
worker.onmessage = function(e) {
    alert('Response: ' + e.data);
};
worker.postMessage('Test');

Cheers,
 Rob
 https://robwu.nl
Reply all
Reply to author
Forward
0 new messages