Javascript 如何使用WebWorkers和Webextensions?

Javascript 如何使用WebWorkers和Webextensions?,javascript,web-worker,firefox-addon-webextensions,Javascript,Web Worker,Firefox Addon Webextensions,我试图在我的webextension中使用一个webworker来加快运行速度,但我似乎连MDN提供的演示webworker示例都无法运行。这是我的舱单: { "manifest_version": 2, "name": "test", "version": "1.0.0", "content_scripts": [ { "matches": [ "http://*/*", "https://*/*" ],

我试图在我的webextension中使用一个webworker来加快运行速度,但我似乎连MDN提供的演示webworker示例都无法运行。这是我的舱单:

{
  "manifest_version": 2,
  "name": "test",
  "version": "1.0.0",

  "content_scripts": [
    {
      "matches": [
        "http://*/*",
        "https://*/*"
      ],
      "js": [
        "sharedTest.js"
      ]
    }
  ]
}
这是sharedTest.js:

console.log("js loaded");
if (window.Worker) { // Check if Browser supports the Worker api.
    // Requires script name as input
    var myWorker = new Worker(browser.runtime.getURL('testWorker.js'));
    myWorker.onmessage = function(e) {
        console.log('Message received from worker');
    console.log(e.data);
    };
  myWorker.postMessage([42, 23]); // Sending message as an array to the worker
  console.log('Message posted to worker');
}
这是testWorker.js:

onmessage = function(e) {
  console.log('Message received from main script');
  var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
  console.log('Posting message back to main script');
  postMessage(workerResult);
}

如果有人能告诉我我做错了什么,或者我的清单中缺少了什么,那就太好了。

因此,由于同源策略,您不能在webextensions中使用普通的web工作人员。但是,您可以通过将工作人员包装成一团来解决此问题,如下所示:

var blob = new Blob([
    `onmessage = function(e) {
       console.log('Message received from main script');
       var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
       console.log('Posting message back to main script');
       postMessage(workerResult);
     }`]);

// Obtain a blob URL reference to our worker 'file'.
var blobURL = window.URL.createObjectURL(blob);

var worker = new Worker(blobURL);
worker.onmessage = function(e) {
    console.log('Message received from worker');
    console.log(e.data);
};
  worker.postMessage([42, 23]); // Sending message as an array to the worker
  console.log('Message posted to worker');
这会奏效的。上面的例子是基于webextensions的,并且在webextensions中是有效的(理论上,除了InternetExplorer之外,其他一切都适用)。但是,该blob worker不再与扩展的其余部分位于同一来源中,因此由于同一来源策略,全局importScripts()将无法导入扩展中的任何文件。这意味着您必须在Blob中包含所有必要的方法和逻辑,这并不理想


或者,我意识到这就是我们的目的,或者我的情况。

似乎可以从背景页创建工人!虽然最初的问题看起来像是他们试图使用内容脚本,但该功能似乎不可用

下面是一个在后台页面上生成web worker的愚蠢、缺乏想象力的示例:

manifest.json:

background.html:


background.js:

if(window.Worker)
{
constmyworker=newworker(browser.runtime.getURL('Worker.js');
myWorker.onmessage=函数(msg){
log(“主脚本:消息已接收”,msg.data);
}
设i=0;
setInterval(()=>{myWorker.postMessage({num:i++});},500);
}
其他的
{
console.log(“不支持工作线程:(”)
}
worker.js:

onmessage=函数(msg)
{
postMessage({timestamp:Date.now(),passedData:msg.data});
}

如果您需要使用内容脚本,则可以使用将消息从脚本发送到后台页面,然后再发送回来。

这可能是一个老问题,但如果有人正在寻找除使用blob或后台脚本以外的解决方案,则可能就是这样-没有任何警告

如果尝试使用当前的manifest.js加载WebWorker,将出现错误。但是,您可以将worker.js文件添加为附加资源,以便浏览器可以访问它。您可以通过向manifest.json添加键来完成此操作。注意:指定为键的值的路径将相对于清单文件

{
  "manifest_version": 2,
  "name": "MyExtension",
  "version": "1.0",

  "content_scripts": [
    {
      "all_frames": true,
      "matches": [ "<all_urls>" ],
      "js": [ "js/content.js", "js/import.js" ],
      "run_at": "document_end",
      "css": ["css/style.css"]
    }
  ],
  "web_accessible_resources": [ "js/worker.js", "pictures/cat.svg" ]
}
要将脚本导入工作程序,首先需要在清单(相对于清单的路径)中将其指定为内容脚本。然后在工作程序中,您可以将其导入为:

self.importScripts('import.js');
self.onmessage = (e) => importStuff.doWork(e); 
此处导入脚本的路径是相对于辅助文件本身的

这就是它-享受线程扩展

const worker = new Worker(browser.runtime.getURL('js/worker.js'));
worker.onmessage = (e) => {window.console.log(e);
self.importScripts('import.js');
self.onmessage = (e) => importStuff.doWork(e);