javascript 从 Greasemonkey 到 Page 访问变量,反之亦然
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13485122/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Accessing Variables from Greasemonkey to Page & vice versa
提问by cryptic ツ
I have the following code in test.jswhich is run right before </body>:
我在test.js 中有以下代码,它在 </body> 之前运行:
alert('stovetop');
alert(greasy);
I have the following code in test.user.js:
我在test.user.js 中有以下代码:
(function () {
'use strict';
var greasy = 'greasy variable';
document.title = 'greasy title';
}());
'stovetop' gets alerted so I know the page javascript works, and document.title
gets changes so I know that the script javascript works. However, on the webpage I get the error:
'stovetop' 收到警报,所以我知道页面 javascript 有效,并document.title
获得更改,因此我知道脚本 javascript 有效。但是,在网页上我收到错误消息:
Error: ReferenceError: greasy is not defined Source File: /test.js
错误:ReferenceError:greasy 未定义源文件:/test.js
How from the webpage do I access the variable set by Greasemonkey and how about vice versa?
我如何从网页访问由 Greasemonkey 设置的变量,反之亦然?
回答by Brock Adams
Greasemonkey scripts operate in a separate scope and may also operate in a sandbox, depending on the
@grant
settings.Additionally, the question code isolates
greasy
in a function scope (as gladoscc said).Finally, by default, test.jswill fire before the Greasemonkey script does, so it won't see any set variables, anyway. Use
@run-at document-start
to address that.
Greasemonkey 脚本在单独的范围内运行,也可能在沙箱中运行,具体取决于
@grant
设置。此外,问题代码
greasy
在函数范围内隔离(如gladoscc 所说)。最后,默认情况下,test.js将在 Greasemonkey 脚本执行之前触发,因此无论如何它都不会看到任何设置的变量。使用
@run-at document-start
来解决这个问题。
So, given this test.js, run right before </body>
:
所以,给定这个test.js,在之前运行</body>
:
window.targetPages_GlobalVar = 'stovetop';
console.log ("On target page, local global: ", targetPages_GlobalVar);
console.log ("On target page, script global: ", gmScripts_GlobalVar);
Then the following will work:
然后以下将起作用:
No sandbox:
没有沙箱:
// ==UserScript==
// @name _Greasemonkey and target page, variable interaction
// @include http://YOUR_SERVER.COM/YOUR_PATH/*
// @include http://output.jsbin.com/esikut/*
// @run-at document-start
// @grant none
// ==/UserScript==
//--- For @grant none, could also use window. instead of unsafeWindow.
unsafeWindow.gmScripts_GlobalVar = 'greasy';
console.log ("In GM script, local global: ", unsafeWindow.targetPages_GlobalVar);
console.log ("In GM script, script global: ", gmScripts_GlobalVar);
window.addEventListener ("DOMContentLoaded", function() {
console.log ("In GM script, local global, after ready: ", unsafeWindow.targetPages_GlobalVar);
}, false);
With sandbox, no function scope, unsafeWindow
:
==> Important update:Greasemonkey changed unsafeWindow handling with version 2.0, the next sample script will not work with GM 2.0 or later. The other two solutions still work.
使用沙箱,没有函数作用域,unsafeWindow
:
==>重要更新:Greasemonkey 在 2.0 版中更改了 unsafeWindow 处理,下一个示例脚本将不适用于 GM 2.0 或更高版本。其他两种解决方案仍然有效。
// ==UserScript==
// @name _Greasemonkey and target page, variable interaction
// @include http://YOUR_SERVER.COM/YOUR_PATH/*
// @include http://output.jsbin.com/esikut/*
// @run-at document-start
// @grant GM_addStyle
// ==/UserScript==
/*- The @grant directive is needed to work around a design change
introduced in GM 1.0. It restores the sandbox.
*/
unsafeWindow.gmScripts_GlobalVar = 'greasy';
console.log ("In GM script, local global: ", unsafeWindow.targetPages_GlobalVar);
console.log ("In GM script, script global: ", unsafeWindow.gmScripts_GlobalVar);
window.addEventListener ("DOMContentLoaded", function() {
console.log ("In GM script, local global, after ready: ", unsafeWindow.targetPages_GlobalVar);
}, false);
With sandbox, no function scope, Script Injection:
使用沙箱,没有函数作用域,脚本注入:
// ==UserScript==
// @name _Greasemonkey and target page, variable interaction
// @include http://YOUR_SERVER.COM/YOUR_PATH/*
// @include http://output.jsbin.com/esikut/*
// @run-at document-start
// @grant GM_addStyle
// ==/UserScript==
/*- The @grant directive is needed to work around a design change
introduced in GM 1.0. It restores the sandbox.
*/
function GM_main () {
window.gmScripts_GlobalVar = 'greasy';
console.log ("In GM script, local global: ", window.targetPages_GlobalVar);
console.log ("In GM script, script global: ", window.gmScripts_GlobalVar);
window.addEventListener ("DOMContentLoaded", function() {
console.log ("In GM script, local global, after ready: ", window.targetPages_GlobalVar);
}, false);
}
addJS_Node (null, null, GM_main);
function addJS_Node (text, s_URL, funcToRun, runOnLoad) {
var D = document;
var scriptNode = D.createElement ('script');
if (runOnLoad) {
scriptNode.addEventListener ("load", runOnLoad, false);
}
scriptNode.type = "text/javascript";
if (text) scriptNode.textContent = text;
if (s_URL) scriptNode.src = s_URL;
if (funcToRun) scriptNode.textContent = '(' + funcToRun.toString() + ')()';
var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
targ.appendChild (scriptNode);
}
Notes:
笔记:
- You can test these script against this page(output.jsbin.com/esikut/1).
- With no sandbox,
unsafeWindow
andwindow
are the same. All of these scripts produce the same output on the console:
In GM script, local global: undefined In GM script, script global: greasy On target page, local global: stovetop On target page, script global: greasy In GM script, local global, after ready: stovetop
The Script Injectioncode will work in a variety of browsers besides Firefox.
unsafeWindow
currently only works in Firefox+Greasemonkey(or Scriptish) or Chrome+Tampermonkey.
- 您可以针对此页面(output.jsbin.com/esikut/1)测试这些脚本。
- 没有沙箱,
unsafeWindow
和window
都是一样的。 所有这些脚本在控制台上产生相同的输出:
In GM script, local global: undefined In GM script, script global: greasy On target page, local global: stovetop On target page, script global: greasy In GM script, local global, after ready: stovetop
该脚本注入代码将在各种除了Firefox浏览器的工作。
unsafeWindow
目前仅适用于 Firefox+Greasemonkey(或 Scriptish)或 Chrome+Tampermonkey。
回答by apscience
Your variable greasy
is defined in the scope of the anonymous function. You cannot access greasy
even in your userscript, unless it is part of your function. Example:
您的变量greasy
是在匿名函数的范围内定义的。您greasy
甚至无法在您的用户脚本中访问,除非它是您的功能的一部分。例子:
(function(){
var foo = 5;
alert(foo);
}();
alert(foo); //ERROR, because foo is undefined outside of the function.
Do it this way:
这样做:
var foo = 5;
(function(){
alert(foo);
}();
alert(foo);
Also, why are you putting all your code in an anonymous function and then executing it?
另外,为什么要将所有代码放在匿名函数中然后执行?
回答by Pikamander2
You can also use localStorage:
您还可以使用localStorage:
localStorage.setItem("numberOfThings", "42");
localStorage.getItem("numberOfThings");