如何从字符串创建Web Worker

big*_*ind 76 javascript web-worker data-uri

如何使用从字符串创建Web worker(通过POST请求提供)?

我能想到的一种方法,但我不确定如何实现它,是通过从服务器响应创建数据URI,并将其传递给Worker构造函数,但我听说有些浏览器不允许这,因为相同的原产地政策.

MDN陈述围绕数据URI的原始政策的不确定性:

注意:作为Worker构造函数的参数传递的URI必须遵循同源策略.目前,浏览器供应商对数据URI是否来源不一致存在分歧; Gecko 10.0(Firefox 10.0/Thunderbird 10.0)及更高版本确实允许数据URI作为工作人员的有效脚本.其他浏览器可能不同意.

这里还有一篇关于whatwg讨论它的帖子.

Rob*_*b W 133

摘要

  • blob: 适用于Chrome 8 +,Firefox 6 +,Safari 6.0 +,Opera 15+
  • data:application/javascript 适用于Opera 10.60 - 12
  • eval 否则(IE 10+)

URL.createObjectURL(<Blob blob>)可用于从字符串创建Web worker.可以使用不推荐使用的BlobBuilderAPI 或构造函数创建blob .Blob

演示:http://jsfiddle.net/uqcFM/49/

// URL.createObjectURL
window.URL = window.URL || window.webkitURL;

// "Server response", used in all examples
var 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');
Run Code Online (Sandbox Code Playgroud)

兼容性

以下浏览器支持Web worker :

  • Chrome 3
  • Firefox 3.5
  • IE 10
  • 歌剧院10.60
  • Safari 4

此方法的支持基于BlobAPI和方法的支持URL.createObjectUrl.Blob兼容性:

  • Chrome 8+(WebKitBlobBuilder),20 +(Blob构造函数)
  • Firefox 6 +(MozBlobBuilder),13 +(Blob构造函数)
  • Safari 6+(Blob构造函数)

IE10支持MSBlobBuilderURL.createObjectURL.但是,尝试从blob:-URL 创建Web Worker 会引发SecurityError.

Opera 12不支持URLAPI.有些用户可能有一个虚假版本的URL对象,这要归功于这个黑客攻击browser.js.

后备1:数据URI

Opera支持将data-URI作为Worker构造函数的参数.注意:不要忘记转义特殊字符(例如#%).

// response as defined in the first example
var worker = new Worker('data:application/javascript,' +
                        encodeURIComponent(response) );
// ... Test as defined in the first example
Run Code Online (Sandbox Code Playgroud)

演示:http://jsfiddle.net/uqcFM/37/

后备2:评估

eval 可以用作Safari(<6)和IE 10的后备.

// Worker-helper.js
self.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 example
worker.postMessage(response);
// .. Test as defined in the first example
Run Code Online (Sandbox Code Playgroud)

  • @BrianFreid感谢您的编辑,但不需要.如果你再看几行,你会看到"IE10支持`MSBlobBuilder`和`URL.createObjectURL`.但是,尝试从`blob:`-URL创建一个Web Worker会抛出一个SecurityError.".因此,添加"MSBlobBuilder"将没有任何效果,唯一的选择是回退#2. (2认同)
  • 我已经确认这仍然发生在IE11中,至少在预览中. (2认同)

Cha*_*dla 8

我同意目前接受的答案,但经常编辑和管理工作人员代码将是繁忙的,因为它是一个字符串的形式.

所以我们可以选择使用下面的方法,我们可以将worker作为一个函数,然后转换为string-> blob:

// function to be your worker
function 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 string
var blob = new Blob([dataObj.replace('"use strict";', '')]); // firefox adds "use strict"; to any function which might block worker execution so knock it off

var blobURL = (window.URL ? URL : webkitURL).createObjectURL(blob, {
    type: 'application/javascript; charset=utf-8'
});


var worker = new Worker(blobURL); // spawn new worker

worker.onmessage = function(e) {
    console.log('Worker said: ', e.data); // message received from worker
};
worker.postMessage("some input to worker"); // Send data to our worker.
Run Code Online (Sandbox Code Playgroud)

这是在IE11 +和FF以及Chrome中测试的


tru*_*ktr 5

由于支持向后兼容性,接受的答案有点复杂,所以我想发布相同但简化的内容。在您的(现代)浏览器控制台中试试这个:

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.
Run Code Online (Sandbox Code Playgroud)