当尝试从 Javascript 中的字符串检索全局上下文中定义的变量(通常是
window
)时,我知道你可以简单地这样做:
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
。
编辑:我还在控制台中从上面的测试上下文对象中进行了侦察,其中没有一个包含我试图检索的变量的任何痕迹。
您使用的是哪种浏览器?
Chrome 和 Firefox 之间存在一些行为差异。例如:
在 Chrome 中,
始终在 内容脚本,不在页面上下文中。eval()
在火狐浏览器中:
- 如果您调用
,它会在内容脚本的上下文中运行代码。eval()
- 如果您调用
,它会在上下文中运行代码 页面的。window.eval()
var
在其范围内是全球性的。
内容脚本在自己的范围内运行。否则,页面脚本可以运行内容脚本中的函数,从而在浏览器中运行并创建安全漏洞。
AFAIK GreaseMonkey/ViolentMonkey/TamperMonkey 将每个用户脚本沙箱化,而 FireMonkey(仅限 Firefox)使用专用的 userScript API,为每个用户脚本创建一个安全范围。
因此,
var testVar = 123;
仅在脚本内容范围内可见。
window
对象是包含用户范围和页面范围的整体对象。
例如:
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
还应该由脚本管理器注入到与其所需的用户脚本相同的上下文/范围(即内容范围)中。
为了更准确地回答,还得看实际代码。
我试图从网站获取变量,有办法做到这一点吗?