我编写了一个 GreaseMonkey (javascript) 用户脚本,该脚本在浏览器 (Firefox) 选项卡中运行,指向
www.site1.com/stuff
。另一个选项卡指向 www.site1.com
(没有 stuff
),并且不是第一个选项卡的子窗口(例如,不是通过在第一个选项卡上运行的用户脚本打开的)。用户脚本在两个选项卡上运行(独立?)。
我希望第一个浏览器选项卡上的用户脚本执行将字符串变量传递到第二个浏览器选项卡。虽然
GM_setValue
和 GM_getValue
非常适合在单个用户脚本中进行存储/检索,但该存储区域似乎无法被用户脚本的其他执行访问。 localStorage
也遭受同样的失败。举个明确的例子:
当用户脚本检测到它正在
www.site1.com/stuff
上运行时,它会将一个值放入存储中:GM_setValue('parValue', 'aaabbbccc');
第一个选项卡完全加载并有足够的时间将该值放入存储后,手动打开第二个选项卡。当用户脚本检测到第二个选项卡在
www.site1.com
(没有 stuff
)上运行时,代码会尝试检索值:var parVal = GM_getValue('parValue')
。在我的用户脚本中,parVal 将具有 null
值;每个用户脚本执行似乎都使用不同的存储区域。
如何实现这个看似简单的任务,即在以下约束下使同一用户脚本的两次执行安全/从公共存储区域检索:
stuff
可以由用户随意更改(为每种可能的 stuff
可能性编写单独的用户脚本是不可能的)。是否有某种可以使用的全局、跨表存储区域,可以在 GreaseMonkey 用户脚本中实现?理论上来说,
GM_setValue
应该适用于这种情况吗?我花了大量时间研究以下相关 SO 问题的答案,但无法找到适用于上述条件集和/或可以实现到 GreaseMonkey 用户脚本中的解决方案:选项卡之间的通信或windows、JavaScript:在选项卡之间共享数据、https://superuser.com/questions/1005448/can-a-greasemonkey-script-know-whats-been-loaded-into-another-tab、发送使用 JavaScript 向所有打开的窗口/选项卡发送消息,
事实证明,“GM_setValue/getValue”确实允许在并行运行相同用户脚本的两个选项卡之间共享信息。我用下面的测试代码证明了这一点。我从一个指向
www.google.com
的选项卡开始,收到警报,然后在同一浏览器窗口中打开另一个选项卡,并将 URL 定向到 www.yahoo.com。该警报表明已成功从在 google.com
上执行的用户脚本放置该值的存储中检索该值。
// ==UserScript==
// @name hello world
// @namespace http://www.sharelatex.com
// @include https://www.google.com/*
// @include https://www.yahoo.com/*
// @grant GM_setValue
// @grant GM_getValue
// ==/UserScript==
if (window.location.href.indexOf("google.com") != -1) { // on Google URL
alert("on Google site, storing value");
// you will see the above alert verifying that code understands
// the code is running on the google.com tab
GM_setValue('passValue', 'aabbcc');
} else {
alert("on Yahoo site, retrieving value");
// the above alert will be seen, verifying that the code
// understands the code is running on the yahoo.com tab
var pvalue = GM_getValue('passValue');
alert("The retrieved value is " + pvalue);
// the above alert should show aabbcc, verifying that the
// userscript running on google.com successfully stored the value
// and the script on yahoo.com successfully retrieved it.
}