Javascript 可以在Greasemonkey脚本中使用worker吗?

Javascript 可以在Greasemonkey脚本中使用worker吗?,javascript,firefox,greasemonkey,Javascript,Firefox,Greasemonkey,我想使用Firefox3.5中引入的Web Worker工具来增强我正在编写的Greasemonkey脚本 这可能吗 我已经做了一些实验,但我无法克服从任意域加载工作脚本的问题 例如,这不起作用: var myWorker = new Worker("http://dl.getdropbox.com/u/93604/js/worker.js"); 此代码在我的Firebug控制台中生成错误消息: 无法加载脚本: (nsresult=0x805303f4) 显然,有一个限制不允许您从与调用脚本的

我想使用Firefox3.5中引入的Web Worker工具来增强我正在编写的Greasemonkey脚本

这可能吗

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

例如,这不起作用:

var myWorker = new Worker("http://dl.getdropbox.com/u/93604/js/worker.js");
此代码在我的Firebug控制台中生成错误消息:

无法加载脚本: (nsresult=0x805303f4)

显然,有一个限制不允许您从与调用脚本的基本URL不相关的URL启动工作程序。您可以在相对URL处加载工作脚本,如下所示:

var myWorker = new Worker("worker.js");
但是我无法在用户的文件系统上获取worker脚本,这样它就可以位于相对于调用脚本的路径上

我在这里搞砸了吗?我应该放弃在Greasemonkey脚本中使用worker吗?

请参阅:


多年来,我一直认为在通用汽车公司不可能使用网络工作者。当然,第一个想法是使用数据URL。但是
工人
构造函数似乎不接受他们

今天我又试了一次,一开始没有任何问题。只有当我开始使用GM API的函数时,
Worker
构造函数才停止工作

Firefox似乎有一个bug,它阻止你从带有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 = unsafeWindow.Worker(dataURL);
或者,您也可以使用blob URL:

var blob = new Blob([script], {type: 'text/javascript'});
var blobURL = URL.createObjectURL(blob);
var worker = new unsafeWindow.Worker(blobURL);
URL.revokeObjectURL(blobURL);
如果确实要使用托管在不同域上的脚本,这不是问题,因为同源策略不适用于
GM\u 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);
        }
    });
}
到现在(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 ou Violentmonkey),由于CSP工人src(请参阅第页的违规案例),我无法工作。这就是为什么不能使用HTTP URL或字符串作为辅助构造函数的参数,在这种非常特殊的情况下,只能使用blob URL


尽管如此,关于工人的背景还是有一个陷阱。他们无法访问DOM、窗口、文档或父对象(请参阅上的workers可用功能)。

我认为Greasemonkey的上下文使其独一无二。众所周知,Greasemonkey支持通常不可能实现的场景,如跨域Ajax请求。也许其他Greasemonkey用户也知道一些可以帮助我的技巧。有一些人为Gears WorkerPool代码编写了一些黑客程序(请查看交叉源标记:)。Greasemonkey还运行在Firefox中的扩展域中,因此MDC归档上的扩展内部工作人员指南可能会有所帮助。可能可以通过chrome::url加载JS。greasemonkey使其唯一的唯一方法是添加代码使其唯一。greasemonkey脚本只能从同一来源加载脚本,这就是它失败的原因。但是,由于greasemonkey使跨域Ajax请求成为可能,您可以先下载脚本,然后无限制地运行它。