Javascript GreaseMonkey-在同一选项卡中运行的两个脚本之间共享数据

Javascript GreaseMonkey-在同一选项卡中运行的两个脚本之间共享数据,javascript,firefox,greasemonkey,Javascript,Firefox,Greasemonkey,有没有办法在同一选项卡中运行的两个不同的greasemonkey脚本之间共享数据?我尝试只设置文档的属性,但没有成功 例如,两个脚本如下所示: if (document.shared === undefined) { document.shared = 0; } document.shared++; 运行该脚本时,无论脚本以何种顺序执行,每个脚本都会初始化变量并将其增量为1(根据实际脚本的日志记录),而不是只初始化其中一个然后共享变量 看起来,对于用户定义的属性,每个GM脚本都会获得自

有没有办法在同一选项卡中运行的两个不同的greasemonkey脚本之间共享数据?我尝试只设置
文档的属性
,但没有成功

例如,两个脚本如下所示:

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;