Javascript GreaseMonkey-在同一选项卡中运行的两个脚本之间共享数据
有没有办法在同一选项卡中运行的两个不同的greasemonkey脚本之间共享数据?我尝试只设置Javascript GreaseMonkey-在同一选项卡中运行的两个脚本之间共享数据,javascript,firefox,greasemonkey,Javascript,Firefox,Greasemonkey,有没有办法在同一选项卡中运行的两个不同的greasemonkey脚本之间共享数据?我尝试只设置文档的属性,但没有成功 例如,两个脚本如下所示: if (document.shared === undefined) { document.shared = 0; } document.shared++; 运行该脚本时,无论脚本以何种顺序执行,每个脚本都会初始化变量并将其增量为1(根据实际脚本的日志记录),而不是只初始化其中一个然后共享变量 看起来,对于用户定义的属性,每个GM脚本都会获得自
文档的属性
,但没有成功
例如,两个脚本如下所示:
if (document.shared === undefined) {
document.shared = 0;
}
document.shared++;
运行该脚本时,无论脚本以何种顺序执行,每个脚本都会初始化变量并将其增量为1(根据实际脚本的日志记录),而不是只初始化其中一个然后共享变量
看起来,对于用户定义的属性,每个GM脚本都会获得自己的文档副本,这根本不是我想要的
另外,显然,两个调用类似于document.getElementById()
的GreaseMonkey脚本将访问同一页面,但显然不访问用户定义的属性。这两个脚本实际上都在沙箱中运行,并且无法访问彼此及其属性。我认为在这两个属性之间进行通信的最佳方式是在HTML中创建一个通信元素,其中包含一些JSON或简单的一些数据作为属性,并以这种方式进行通信。然后定期检查具有预定ID的元素,在找到JSON时解码并返回一些数据
请记住,数据之间的作用域和链接的任何实例都不会保留。这意味着您不能以这种方式传递任何函数,以防止您仍然在脚本之间通信,但只要您能够JSON,简单地传递一些数据(如数组、对象、数字或字符串)应该是没有问题的
var me = /* some id */;
window.addEventListener("message", function(e) {
if(e.origin === location.origin && typeof e.data === 'object' && e.data.sender !== me) {
console.log('received in script ' + me +': ', e.data.data);
}
});
document.addEventListener('DOMContentLoaded', function() {
window.postMessage({sender: me, data: 'message from script ' + me}, location.origin);
});
如果将该脚本与me=1
和me=2
一起使用两次,您将看到
在脚本2中收到:来自脚本1的消息
在脚本1中收到:来自脚本2的消息
一些注意事项:
- 使用
@Run at document start
运行脚本,并等待DOMContentLoaded
发送数据。通过这种方式,您将确保已添加事件侦听器
- 如果使用
@grant none
,页面将能够通过修改addEventListener
或postMessage
劫持消息
为了避免这种情况,您可以使用沙箱存储脚本,例如@grant GM_info
。这还将提供一种为me
生成id的方法(如果您不介意将此信息泄漏到页面):
- 该页面将能够读取脚本发送的消息,甚至可以像发送任何脚本一样向脚本发送消息
因此,不要发送敏感数据,也不要信任接收到的数据
对于这样简单的事情,只需使用unsafeWindow.shared
。是否可以在两个脚本中添加事件侦听器,然后发送任何需要发送的数据事件?这避免了必须操纵DOM来发送消息。可能只是postMessage
将消息返回到窗口,并让两个脚本都收听message
。根据Oriol的回答,这似乎是可能的。我得说我自己还没有测试过,但听起来有可能。
me = GM_info.script.name + GM_info.script.namespace;