How to create a Web Worker from a string How to create a Web Worker from a string javascript javascript

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 - 12
  • eval 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.