简体   繁体   English

如何使用 GreaseMonkey/ViolentMonkey 从字符串中检索全局上下文变量?

[英]How to retrieve a global context variable from a string using GreaseMonkey/ViolentMonkey?

When trying to retrieve a variable defined in global context (usually window ) from a string in Javascript, I know that you can simply do it like this:当尝试从 Javascript 中的字符串检索在全局上下文(通常是window )中定义的变量时,我知道您可以简单地这样做:

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

However, inside a content-injected userscript I wrote for ViolentMonkey this simply returns undefined , seemingly because the global context works differently there than in an usual page script.然而,在我为 ViolentMonkey 编写的内容注入用户脚本中,这只是返回undefined ,似乎是因为全局上下文的工作方式与通常的页面脚本不同。 I tried different ways of accessing the global context:我尝试了不同的访问全局上下文的方法:

// ==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"

All of which are not working.所有这些都不起作用。 Is there some way I can access the global context inside an userscript, or even a different way to retrieve a variable from a string?有什么方法可以访问用户脚本中的全局上下文,甚至是从字符串中检索变量的不同方法?

What I'm trying to achieve at the end is to instantiate a class object from one of a bunch of externally loaded classes where the class used depends on the site URL.我最后想要实现的是从一堆外部加载的类中的一个实例化一个类对象,其中使用的类取决于站点 URL。

If possible, I'd like to avoid defining the classes in namespaces, which would be refactoring hell for me, or the use of eval for obvious reasons.如果可能,我想避免在命名空间中定义类,这对我来说是重构地狱,或者出于显而易见的原因使用eval

EDIT: I've also scouted through the tested context objects from above in the console, none of which contains any trace of the variable I'm trying to retrieve.编辑:我还在控制台中从上面搜索了经过测试的上下文对象,其中没有一个包含我试图检索的变量的任何痕迹。

Which browser are you using?您使用的是哪个浏览器?
There are some behavioural differences between Chrome & Firefox. Chrome 和 Firefox 之间存在一些行为差异。 For example:例如:

In Chrome, eval() always runs code in the context of the content script, not in the context of the page.在 Chrome 中, eval()总是在内容脚本的上下文中运行代码,而不是在页面的上下文中。

In Firefox:在 Firefox 中:

  • If you call eval() , it runs code in the context of the content script.如果您调用eval() ,它会在内容脚本的上下文中运行代码。
  • If you call window.eval() , it runs code in the context of the page.如果您调用window.eval() ,它会在页面上下文中运行代码。

source: Using eval() in content scripts来源: 在内容脚本中使用 eval()

var is global within its scope. var在其范围内是全局的。

Content scripts run in their own scope.内容脚本在它们自己的范围内运行。 Otherwise page script can run functions in content script and thus browser and create a security hole.否则页面脚本可以在内容脚本和浏览器中运行功能并创建安全漏洞。

AFAIK GreaseMonkey/ViolentMonkey/TamperMonkey sandbox each user-script, while FireMonkey (Firefox only) uses the dedicated userScript API which creates a secure scope for each user-script. AFAIK GreaseMonkey/ViolentMonkey/TamperMonkey 沙箱每个用户脚本,而 FireMonkey(仅限 Firefox)使用专用的 userScript API,它为每个用户脚本创建一个安全范围。

Therefore, var testVar = 123;因此, var testVar = 123; is only visible within the script content scope.仅在脚本内容范围内可见。

window object is the overall object that contains both the user scope and page scope. window对象是包含用户范围和页面范围的整体对象。

For example:例如:

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"

Note: tested with FireMonkey注意:用 FireMonkey 测试

trying to retrieve a variable defined in global context (usually window)试图检索在全局上下文中定义的变量(通常是窗口)

For getting a variable defined in page context (as oppose to setting it), there are a few options which depends on the situation:为了获取在页面上下文中定义的变量(与设置它相反),有几个选项取决于具体情况:

@require @要求

@require should also be injected into the same context/scope as the user-script that it has required it, which is the content scope, by the script managers. @require还应该被脚本管理器注入到与它需要它的用户脚本相同的上下文/范围中,这是内容范围。

In order to answer more precisely, the actual code has to be seen.为了更准确地回答,必须查看实际代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM