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

时间:2015-12-12 02:03:39

标签: javascript firefox greasemonkey

有没有办法在同一个标​​签中运行的两个不同的greasemonkey脚本之间共享数据?我尝试设置document的属性,但它没有用。

例如,两个脚本都是这样的:

if (document.shared === undefined) {
    document.shared = 0;
}
document.shared++;

当运行它时,无论脚本执行的顺序如何,每个脚本都会初始化变量并将其增加到1(根据实际脚本中的日志记录),而不是只有其中一个初始化然后共享变量。

对于用户定义的属性,似乎每个GM脚本都拥有它自己的document副本,这根本不是我想要的。

P.S。显然,调用document.getElementById()之类的两个GreaseMonkey脚本将访问同一页面,但显然不会访问用户定义的属性。

2 个答案:

答案 0 :(得分:2)

这两个脚本实际上都在沙箱中运行,并且无法访问彼此及其属性。我认为在这两个属性之间进行通信的最佳方式是在HTML中创建一个包含一些JSON的通信元素,或者只是将一些数据作为属性创建并以这种方式进行通信。然后定期检查具有预定ID的元素,在找到时解码JSON并发回一些数据。

请记住,数据之间的任何范围和链接的实例都不会保留。这意味着您不能以这种方式传递任何函数以防止您仍然在脚本之间进行通信,但只要传递一些数据(例如数组,对象,数字或字符串)应该没有问题,只要您可以JSON.stringify它们。

答案 1 :(得分:0)

您可以使用网络消息,例如

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 = 1me = 2两次使用该脚本,则会看到

received in script 2: message from script 1
received in script 1: message from script 2

一些注意事项:

  • 使用@run-at document-start运行脚本,并在发送数据之前等待DOMContentLoaded。这样您就可以确定已添加事件侦听器。

  • 如果您使用@grant none,该页面将能够通过修改addEventListenerpostMessage来劫持消息。

    为避免这种情况,您可以使用以下方法对脚本进行沙盒处理。 @grant GM_info。这也将提供一种为me生成ID的方法(如果您不关心将此信息泄露到页面中):

    me = GM_info.script.name + GM_info.script.namespace;
    
  • 该页面将能够读取您的脚本发送的消息,甚至可以将消息发送到您的脚本,就像它是您的任何脚本一样。

    因此,请勿发送敏感数据,也不要信任收到的数据。