是否可以在 Greasemonkey 脚本中使用工人?

问题描述 投票:0回答:3

我想使用 Firefox 3.5 中引入的 Web Worker 工具来增强我正在开发的 Greasemonkey 脚本。

这可能吗?

我已经做了一些实验,但我无法解决从任意域加载工作脚本的问题。

例如,这不起作用:

var myWorker = new Worker("http://dl.getdropbox.com/u/93604/js/worker.js");

此代码在我的 Firebug 控制台中生成错误消息:

加载脚本失败: http://dl.getdropbox.com/u/93604/js/worker.js (ns结果 = 0x805303f4)

显然存在一个限制,不允许您从与调用脚本的基本 URL 无关的 URL 启动工作程序。您可以像这样在相对 URL 加载工作脚本:

var myWorker = new Worker("worker.js");

但是我无法在用户的文件系统上获取工作脚本,以便它可以位于相对于调用脚本的路径。

我被搞砸了吗?我应该放弃尝试在 Greasemonkey 脚本中使用工人吗?

javascript firefox greasemonkey
3个回答
15
投票

多年来我一直认为不可能在 GM 中使用 Web Worker。当然,第一个想法是使用 data-urls。但

Worker
构造函数似乎不接受它们。

今天我又尝试了一下,一开始没有任何问题。只有当我开始使用 GM API 的函数时,

Worker
构造函数才停止工作。

Firefox 似乎有一个错误,会阻止您从具有 X 射线视觉的沙箱访问

Worker
。即使评估
typeof Worker
也会引发异常。所以使用workers的唯一方法就是从未包装的窗口中获取未包装的版本:

var echoWorker = new unsafeWindow.Worker("data:text/javascript," +
    "self.onmessage = function(e) {\n" +
    "    self.postMessage(e.data);\n" +
    "};"
);

当然,你必须小心特殊字符。最好用base64对脚本进行编码:

var dataURL = 'data:text/javascript;base64,' + btoa(script);
var worker = new unsafeWindow.Worker(dataURL);

或者,您也可以使用 blob-urls:

var blob = new Blob([script], {type: 'text/javascript'});
var blobURL = URL.createObjectURL(blob);
var worker = new unsafeWindow.Worker(blobURL);
URL.revokeObjectURL(blobURL);

如果您确实想使用托管在不同域上的脚本,这不是问题,因为同源策略不适用于

GM_xmlhttpRequest
:

function createWorkerFromExternalURL(url, callback) {
    GM_xmlhttpRequest({
        method: 'GET',
        url: url,
        onload: function(response) {
            var script, dataURL, worker = null;
            if (response.status === 200) {
                script = response.responseText;
                dataURL = 'data:text/javascript;base64,' + btoa(script);
                worker = new unsafeWindow.Worker(dataURL);
            }
            callback(worker);
        },
        onerror: function() {
            callback(null);
        }
    });
}

7
投票

到目前为止(10 年后),可以将 Web Workers 与 Firefox 77 和 Tampermonkey 一起使用。我已经使用内联工作人员成功进行了测试:

var blob = new Blob(["onmessage = function(e){postMessage('whats up?');console.log(e.data)}"], {type: 'text/javascript'})

var url = URL.createObjectURL(blob)

var worker = new Worker(url)

worker.onmessage = function(e){
  console.log(e.data) 
}

worker.postMessage('hey there!')

使用 Chrome 或其他扩展程序(如 Greasemonkey 或 Violentmonkey),由于 CSP worker-src 的原因,我无法工作(请参阅https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ 上的违规案例)内容-安全-策略/worker-src)。这就是为什么不可能使用 HTTP URL 或字符串作为 Worker 构造函数的参数,只能在这种非常特殊的情况下使用 blob URL。

尽管如此,工人的背景还是有一个问题。他们无法访问 DOM、窗口、文档或父对象(请参阅工作人员可用的功能,网址为 https://www.html5rocks.com/en/tutorials/workers/basics/)。


© www.soinside.com 2019 - 2024. All rights reserved.