Javascript 可以在Greasemonkey脚本中使用worker吗?
我想使用Firefox3.5中引入的Web Worker工具来增强我正在编写的Greasemonkey脚本 这可能吗 我已经做了一些实验,但我无法克服从任意域加载工作脚本的问题 例如,这不起作用: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) 显然,有一个限制不允许您从与调用脚本的
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请求成为可能,您可以先下载脚本,然后无限制地运行它。