我是greasemonkey 的新手,并试图了解greasemonkey 与嵌入式Web 控制台有何不同。一个在 Web 控制台上完美运行的简单脚本在 Greasemonkey 上不起作用,我不知道为什么。
环境
Arch Linux 上的 Firefox 74.0
油猴4.9
网络控制台
这是我使用的测试脚本:
(function() {
"use strict";
const w = window.open('https://www.google.com/', 'w');
console.log("Hello");
w.onload = () => {
console.log("World");
};
})();
当我访问https://www.google.com/webhp?gl=us&hl=en&gws_rd=cr&pws=0时(Google US首页),将脚本复制并粘贴到Web控制台中,然后执行它,
一个新窗口
w
正在加载https://www.google.com/已打开。打印字符串
Hello
。打印字符串
World
。
一切都如预期。
油猴
在greasemonkey上,我使用下面的脚本。 header 部分是唯一的区别。
// ==UserScript==
// @name test
// @namespace n
// @match https://www.google.com/webhp?gl=us&hl=en&gws_rd=cr&pws=0
// ==/UserScript==
(function() {
"use strict";
const w = window.open('https://www.google.com/', 'w');
console.log("Hello");
w.onload = () => {
console.log("World");
};
})();
当我访问https://www.google.com/webhp?gl=us&hl=en&gws_rd=cr&pws=0时(Google 美国首页),
一个新窗口
w
正在加载https://www.google.com/已打开。打印字符串
Hello
。SecurityError
抛出说Script error in [Greasemonkey script n/test]:
SecurityError: Permission denied to access property "onload" on cross-origin object test:42:19
user-script:n/test:42
当我使用 unsafeWindow
而不是 window
时,
一个新窗口
w
正在加载https://www.google.com/已打开。打印字符串
Hello
。没有其他事情发生。 (没有错误,没有
世界
)
问题
我应该如何修改脚本以便可以在greasemonkey上执行?
<小时/>更新
根据this comment ,该脚本适用于 Chrome 下的 Tampermonkey 或 Violentmonkey。
我尚未确认这一点,但已确认该脚本可以在 Firefox 下的 Tampermonkey 4.10.6105
或 Violentmonkey 2.12.7
上运行。
最佳答案
Web 控制台是浏览器范围的一部分,而 GreaseMonkey 脚本被注入(inject)到页面内容中,其范围仅限于该页面。
您可以使用 GM 从页面内容打开一个新选项卡/窗口,但该窗口/选项卡将具有其自己的页面内容范围,该范围与第一个页面内容范围分开。因此,您无法从不同选项卡的页面内容访问属于另一个选项卡/窗口的属性。
这种分离适用于所有内容脚本,而不仅仅是 GM。否则,如果一个选项卡/页面中的 JS 可以访问其他选项卡上的数据,就会产生很大的安全风险。
更新:
正如 wOxxOm 所指出的,CSP 和跨源策略阻止 Cross-Origin Resource Sharing (CORS) .
在您的示例中,在 Firefox 中,第一个问题是 Firefox 将从内容脚本中“阻止弹出窗口”。
测试 Firefox 专用 userScripts API FireMonkey ,允许弹出后,仍然报错:
SecurityError: Permission denied to access property "onload" on cross-origin object
在这种情况下,我认为这是由于出于安全考虑而对 userScripts 进行了沙箱处理。
GM/TM/VM 不使用 userScripts API 并使用其他方式注入(inject) userSripts,这会导致不同的结果。
关于javascript - Greasemonkey 为一个简单的脚本抛出 SecurityError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60903868/