简体   繁体   中英

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:

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. 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.

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.

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. For example:

In Chrome, eval() always runs code in the context of the content script, not in the context of the page.

In Firefox:

  • If you call eval() , it runs code in the context of the content script.
  • If you call window.eval() , it runs code in the context of the page.

source: Using eval() in content scripts

var is global within its scope.

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.

Therefore, 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.

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

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.

In order to answer more precisely, the actual code has to be seen.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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