How to create a Web Worker from a string
Summary
blob:
for Chrome 8+, Firefox 6+, Safari 6.0+, Opera 15+data:application/javascript
for Opera 10.60 - 12eval
otherwise (IE 10+)
URL.createObjectURL(<Blob blob>)
can be used to create a Web worker from a string. The blob can be created using the BlobBuilder
API deprecated or the Blob
constructor.
Demo: http://jsfiddle.net/uqcFM/49/
// URL.createObjectURLwindow.URL = window.URL || window.webkitURL;// "Server response", used in all examplesvar response = "self.onmessage=function(e){postMessage('Worker: '+e.data);}";var blob;try { blob = new Blob([response], {type: 'application/javascript'});} catch (e) { // Backwards-compatibility window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder; blob = new BlobBuilder(); blob.append(response); blob = blob.getBlob();}var worker = new Worker(URL.createObjectURL(blob));// Test, used in all examples:worker.onmessage = function(e) { alert('Response: ' + e.data);};worker.postMessage('Test');
Compatibility
Web workers are supported in the following browsers source:
- Chrome 3
- Firefox 3.5
- IE 10
- Opera 10.60
- Safari 4
This method's support is based on the support of the Blob
API and the URL.createObjectUrl
method. Blob
compatibility:
- Chrome 8+ (
WebKitBlobBuilder
), 20+ (Blob
constructor) - Firefox 6+ (
MozBlobBuilder
), 13+ (Blob
constructor) - Safari 6+ (
Blob
constructor)
IE10 supports MSBlobBuilder
and URL.createObjectURL
. However, trying to create a Web Worker from a blob:
-URL throws a SecurityError.
Opera 12 does not support URL
API. Some users may have a fake version of the URL
object, thanks to this hack in browser.js
.
Fallback 1: data-URI
Opera supports data-URIs as an argument to the Worker
constructor. Note: Do not forget to escape special characters (Such as #
and %
).
// response as defined in the first examplevar worker = new Worker('data:application/javascript,' + encodeURIComponent(response) );// ... Test as defined in the first example
Demo: http://jsfiddle.net/uqcFM/37/
Fallback 2: Eval
eval
can be used as a fallback for Safari (<6) and IE 10.
// Worker-helper.jsself.onmessage = function(e) { self.onmessage = null; // Clean-up eval(e.data);};// Usage:var worker = new Worker('Worker-helper.js');// `response` as defined in the first exampleworker.postMessage(response);// .. Test as defined in the first example
I agree with the current accepted answer but often editing and managing the worker code will be hectic as its in the form of a string.
So optionally we can use the below approach where we can keep the worker as a function, and then covert to string->blob:
// function to be your workerfunction workerFunction() { var self = this; self.onmessage = function(e) { console.log('Received input: ', e.data); // message received from main thread self.postMessage("Response back to main thread"); }}///////////////////////////////var dataObj = '(' + workerFunction + ')();'; // here is the trick to convert the above fucntion to stringvar blob = new Blob([dataObj.replace('"use strict";', '')]); // firefox adds "use strict"; to any function which might block worker execution so knock it offvar blobURL = (window.URL ? URL : webkitURL).createObjectURL(blob, { type: 'application/javascript; charset=utf-8'});var worker = new Worker(blobURL); // spawn new workerworker.onmessage = function(e) { console.log('Worker said: ', e.data); // message received from worker};worker.postMessage("some input to worker"); // Send data to our worker.
This is tested in IE11+ and FF and Chrome
The accepted answer is a bit complex, due to supporting backwards compatibility, so I wanted to post the same thing but simplified. Try this in your (modern) browser console:
const code = "console.log('Hello from web worker!')"const blob = new Blob([code], {type: 'application/javascript'})const worker = new Worker(URL.createObjectURL(blob))// See the output in your console.