greasemonkey 为一个简单的脚本抛出 SecurityError
greasemonkey throws SecurityError for a simple script
我是 greasemonkey 的新手,正在尝试了解 greasemonkey 与嵌入式 Web 控制台的不同之处。一个在 Web 控制台上完美运行的简单脚本在 greasemonkey 上不 运行,我不知道为什么。
环境
Arch 上的 Firefox 74.0 Linux
Greasemonkey 4.9
Web 控制台
这是我使用的测试脚本:
(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美国首页)时,将脚本复制并粘贴到Web控制台,然后执行,
新的windoww
加载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 美国首页)时,
新的windoww
加载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
时,
新的windoww
加载https://www.google.com/打开
打印字符串Hello
而且没有其他事情发生。 (没有错误,没有World
)
问题
我应该如何修改脚本才能在 greasemonkey 上执行?
更新
根据 ,该脚本适用于 Chrome.
下的 Tampermonkey 或 Violentmonkey
我尚未确认这一点,但已确认该脚本在 Firefox.
下的 Tampermonkey 4.10.6105
或 Violentmonkey 2.12.7
上有效
Web 控制台是浏览器范围的一部分,而 GreaseMonkey 脚本被注入到页面内容中并且其范围仅限于该页面。
您可以使用 GM 从页面内容打开一个新的 tab/window,但是 window/tab 将有自己的页面内容范围,与第一个不同。因此,您无法从不同选项卡的页面内容访问属于另一个 tab/window 的属性。
这种分离适用于所有内容脚本,而不仅仅是 GM。否则,如果一个 tab/page 中的 JS 可以访问其他选项卡上的数据,将会产生很大的安全风险。
更新:
正如 wOxxOm 所指出的,CSP 和跨源策略阻止了 Cross-Origin Resource Sharing (CORS)。
在您的示例中,在 Firefox 中,第一个问题是 Firefox 将 "Block pop-up windows" 来自内容脚本。
测试Firefox专用userScripts API on FireMonkey,允许弹出后,仍然报错:
SecurityError: Permission denied to access property "onload" on
cross-origin object
在这种情况下,我认为这是由于为安全起见对 userScripts 进行了沙盒处理。
GM/TM/VM 不要使用 userScripts API 并使用其他方式注入 userSripts,这会导致不同的结果。
我是 greasemonkey 的新手,正在尝试了解 greasemonkey 与嵌入式 Web 控制台的不同之处。一个在 Web 控制台上完美运行的简单脚本在 greasemonkey 上不 运行,我不知道为什么。
环境
Arch 上的 Firefox 74.0 Linux
Greasemonkey 4.9
Web 控制台
这是我使用的测试脚本:
(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美国首页)时,将脚本复制并粘贴到Web控制台,然后执行,
新的window
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 美国首页)时,
新的window
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
时,
新的window
w
加载https://www.google.com/打开打印字符串
Hello
而且没有其他事情发生。 (没有错误,没有
World
)
问题
我应该如何修改脚本才能在 greasemonkey 上执行?
更新
根据
我尚未确认这一点,但已确认该脚本在 Firefox.
下的Tampermonkey 4.10.6105
或 Violentmonkey 2.12.7
上有效
Web 控制台是浏览器范围的一部分,而 GreaseMonkey 脚本被注入到页面内容中并且其范围仅限于该页面。
您可以使用 GM 从页面内容打开一个新的 tab/window,但是 window/tab 将有自己的页面内容范围,与第一个不同。因此,您无法从不同选项卡的页面内容访问属于另一个 tab/window 的属性。
这种分离适用于所有内容脚本,而不仅仅是 GM。否则,如果一个 tab/page 中的 JS 可以访问其他选项卡上的数据,将会产生很大的安全风险。
更新:
正如 wOxxOm 所指出的,CSP 和跨源策略阻止了 Cross-Origin Resource Sharing (CORS)。
在您的示例中,在 Firefox 中,第一个问题是 Firefox 将 "Block pop-up windows" 来自内容脚本。
测试Firefox专用userScripts API on FireMonkey,允许弹出后,仍然报错:
SecurityError: Permission denied to access property "onload" on cross-origin object
在这种情况下,我认为这是由于为安全起见对 userScripts 进行了沙盒处理。
GM/TM/VM 不要使用 userScripts API 并使用其他方式注入 userSripts,这会导致不同的结果。