Is it possible to spawn a web worker, and somehow inject JavaScript functions into it from the parent thread? ie. without having to make the worker include a file, rather I want the parent to inject it somehow.
Asked
Active
Viewed 1,342 times
1
-
3You could transmit the code using the usual `send()` and then use `new Function()` in the worker to convert it into a function. – Sirko Sep 26 '14 at 21:22
1 Answers
2
One option is to send the functions code through the usual channel and use the constructor new Function()
(or eval()
) to recreate the function.
In both cases you should check, what is actually transmitted to prevent security risks.
main script
// your function given as arguments and code
var funktion = {
args: ['a', 'b' ],
source: 'return a + b;'
};
// send it to your worker
worker.postMessage( funktion );
worker
self.addEventListener( 'message', function( msg ){
// build array for constructor arguments
var args = [ null ].concat( fk.a, fk.c );
// create function
var yourFunc = new (Function.prototype.bind.apply(Function, args));
// use yourFunc
});
This uses the dynamic use of the Function
constructor as described in this answer.
Using eval()
may be simpler depending on how you have the function's code:
main script
// your function given as arguments and code
var funktion = "function add(a,b){ return a + b; }";
// send it to your worker
worker.postMessage( funktion );
worker
self.addEventListener( 'message', function( msg ){
// create function
var yourFunc = eval( "(function(){ return " + funktion + "; })()" );
// use yourFunc
});
-
I think it is possible to use a module bundler to bundle modules somehow and send the whole thing to a general web worker through postMessage, which then evals it. It is just a security risk, but you can sign the whole thing and the worker could check the digital signature before evaling. Maybe that gives a little safety, idk. (Still it would not make much sense, because you could use the bundle.js by creating the worker.) – inf3rno Jan 11 '20 at 07:59
-
@inf3rno the bundler changes nothing in the overall concept, I think. your still sending some string with code and evaluating it on the other end. As for security, it highly depends on where the source code is generated. If this is purely within the same browser, I do not really see an security issue, as all you can do is "hack" yourself. – Sirko Jan 11 '20 at 08:45
-
Yes the concept is the same, but with a bundler you can use normal js code instead of writing it as string. Normally you have dependencies and you can send all of them along with the code, not just a single function on closure without external dependencies. Signing it gives a little extra security, because your worker cannot be injected by ppl using XSS. – inf3rno Jan 11 '20 at 08:55