首页 > 解决方案 > 如何使用 GreaseMonkey/ViolentMonkey 从字符串中检索全局上下文变量?

问题描述

当试图window从 Javascript 中的字符串中检索在全局上下文(通常)中定义的变量时,我知道您可以简单地这样做:

var testVar = 123;
console.log(window["testVar"]); // logs "123"

然而,在我为 ViolentMonkey 编写的内容注入用户脚本中,这只是返回undefined,似乎是因为全局上下文的工作方式与通常的页面脚本不同。我尝试了访问全局上下文的不同方法:

// ==UserScript==
// @name        Test
// @namespace   *
// @include     *
// @version     1
// @inject-into content
// @grant       none
// ==/UserScript==

var testVar = 123;

console.log(testVar); // logs "123"
console.log(window.testVar); // logs "undefined"
console.log(window["testVar"]); // logs "undefined"
console.log(this["testVar"]); // logs "undefined"
console.log(unsafeWindow["testVar"]); // logs "undefined"

所有这些都不起作用。有什么方法可以访问用户脚本中的全局上下文,或者甚至是从字符串中检索变量的不同方法?

我最终要实现的是从一堆外部加载的类中的一个实例化一个类对象,其中使用的类取决于站点 URL。

如果可能的话,我想避免在命名空间中定义类,这对我来说将是重构地狱,或者eval出于明显的原因使用。

编辑:我还在控制台中通过上面的测试上下文对象进行了侦察,其中没有一个包含我试图检索的变量的任何痕迹。

标签: javascriptfirefoxwindowgreasemonkey

解决方案


您使用的是哪个浏览器?
Chrome 和 Firefox 之间存在一些行为差异。例如:

在 Chrome 中,eval()始终在内容脚本的上下文中运行代码,而不是在页面的上下文中。

在火狐中:

  • 如果您调用eval(),它将在内容脚本的上下文中运行代码。
  • 如果您调用window.eval(),它将在页面的上下文中运行代码。

来源:在内容脚本中使用 eval()

var在其范围内是全球性的。

内容脚本在它们自己的范围内运行。否则页面脚本可以在内容脚本中运行功能,从而在浏览器中运行并创建安全漏洞。

AFAIK GreaseMonkey/ViolentMonkey/TamperMonkey 沙箱每个用户脚本,而 FireMonkey(仅限 Firefox)使用专用的 userScript API,为每个用户脚本创建一个安全范围。

因此,var testVar = 123;仅在脚本内容范围内可见。

windowobject 是包含用户范围和页面范围的整体对象。

例如:

var testVar = 123;
console.log(testVar);         // logs "123"
console.log(window.testVar);  // logs "undefined"



window.testVar = 456;

console.log(testVar);         // logs "123"
console.log(window.testVar);  // logs "456"

注意:使用 FireMonkey 测试

试图检索在全局上下文(通常是窗口)中定义的变量

为了获得在页面上下文中定义的变量(与设置它相反),有几个选项取决于具体情况:

@要求

@require还应该由脚本管理器注入与它需要的用户脚本相同的上下文/范围,即内容范围。

为了更准确地回答,必须查看实际代码。


推荐阅读