如何设置@grant值时如何访问`window`(目标页面)对象? [英] How to access `window` (Target page) objects when @grant values are set?
问题描述
$ b
< html>
< body>
< span id =click>点击我< / span>
< script>
var hello = function(){
alert('hello');
$ b document.getElementById('click')。addEventListener('click',function(e){
hello();
});
< / script>
< / body>
< / html>
和我的Greasemonkey脚本是:
// == UserScript ==
// @name My Script
// @include http://example.com/hello.html
/ / @version 1
// @grant none
// == / UserScript ==
window.hello = function(){
alert('goodbye' );
禁用Greasemonkey脚本,单击 #click页面上的
元素显示hello警报。启用脚本后,单击该元素将显示再见提醒。
足够简单。网页中的 hello
函数正在被Greasemonkey脚本中的函数取代。
现在让我们来说说I想要使用Greasemonkey API。当我将 @grant
值设置为none以外的有效值(例如 // @grant GM_setClipboard
)时这导致Greasemonkey作为内容脚本运行脚本,而不是像'none'那样在页面的范围内运行,Greasemonkey脚本无法运行。
window.hello
不再针对页面上的正确对象。
替换窗口.hello
与 unsafeWindow.hello
看起来好像会起作用,但是在JS控制台中引发了下面的错误:
错误:拒绝访问对象的权限
在将 @grant GM_setClipboard
设置为target并替换页面上的原始 hello
函数时重写Greasemonkey脚本
系统信息:
$ ul
@grant
Greasemonkey激活它的沙盒,并且 Greasemonkey 2.0从根本上改变了unsafeWindow的处理方式。 现在,为了在目标页面范围内创建或覆盖变量,您必须从技术菜单中正确选择。 EG:
阅读:
-
变量:
目标页面设置:var foo =bar;
GM脚本可以读取:unsafeWindow.foo // - bar
-
一个简单的对象:
目标页面集:var obj = {A:1};
GM脚本可以读取:unsafeWindow.obj // - Object {A:1}
打电话给一个复杂的对象: :
-
一个简单的函数:
目标页面设置:函数func(){console.log('Hi');}
GM脚本可以调用:unsafeWindow.func()// - Hi
-
一个简单的变量:
unsafeWindow.foo =Apple;
-
一个简单的对象:
var gmObject = {X:123};
unsafeWindow.obj = cloneInto(gmObject,unsafeWindow);
-
简单的功能: b
function gmFunc(){
console.log(Lorem ipsum);
// - 可以在这里使用GM_函数! :)
}
unsafeWindow.func = exportFunction(gmFunc,unsafeWindow);
- 这些都是特定于Firefox的。
- 对于跨平台的代码和一些复杂的情况,改为使用 Script Injection 。但注入的代码不能直接访问
GM _
函数。注意,这些技术只适用于全局的javascript变量和函数。 li> - Windows 7 64-bit
- Firefox 32.0
- Greasemonkey 2.2
A simple variable:
Target page sets: var foo = "bar"; GM script can read: unsafeWindow.foo //-- "bar"
A simple object:
Target page sets: var obj = {A: 1}; GM script can read: unsafeWindow.obj //-- Object { A: 1 }
A complex object: This is not always possible.
A simple function:
Target page sets: function func () {console.log ('Hi');} GM script can call: unsafeWindow.func() //-- "Hi"
A complex function: This is not always possible.
A simple variable:
unsafeWindow.foo = "Apple";
A simple object:
var gmObject = {X: "123"}; unsafeWindow.obj = cloneInto (gmObject, unsafeWindow);
A simple function:
function gmFunc () { console.log ("Lorem ipsum"); //-- Can use GM_ functions in here! :) } unsafeWindow.func = exportFunction (gmFunc, unsafeWindow);
- This is all Firefox specific.
- For cross platform code, and for some complex situations, you can use Script Injection instead. But injected code cannot directly access
GM_
functions. - Note that these techniques only work for javascript variables and functions that are global.
写/设置:
<看看这个HTML:
< button id =helloBtn>说Hello。< / button>
而这个javascript:
var simpleGlobalVar =页面范围内的一个简单的全局变量。
var globalObject = {Letter:A,Number:2};
函数simpleFunction(){
console.log(目标页面的simpleFunction被调用。
var sayHello = function(){
console.log('Hello。');
$ b document.getElementById('helloBtn')。addEventListener('click',function(){
sayHello();
});
您可以在 这个jsFiddle页面 。
如果你安装并运行这个Greasemonkey脚本:
// == UserScript ==
// @name _Demonstrate访问目标页面具有@grant值的变量设置
// @include http://fiddle.jshell.net/sepwL7n6/*/show/
// @require http://ajax.googleapis.com/ajax/ libs / jquery / 2.1.0 / jquery.min.js
// @grant GM_addStyle
// == / UserScript ==
console.log(*** Greasemonkey脚本启动);
$ b $(body)。append('< div id =gmArea>添加Greasemonkey:< p>< / p>< / div>');
$(#gmArea> p:first)。append('< button id =gmShow>访问选择目标页面变量和函数< / button>');
$(#gmArea> p:first)。append('< button id =gmChange>在目标页面范围内改变javascript的东西< / button>');
$(#gmShow)。click(function(){
// - 从目标页面范围访问事物:
console.log( - ;
console.log(==> simpleGlobalVar是:,unsafeWindow.simpleGlobalVar);
console.log(= => globalObject is:,unsafeWindow.globalObject);
console.log(==>调用目标的simpleFunction():);
unsafeWindow.simpleFunction();
// - 警告!下一个技巧不是很强大,但是在某些情况下可以使用
console.log(==>调用目标按钮的click()。);
unsafeWindow .document.getElementById('helloBtn')。click();
});点击(函数(){
this.disabled = true; // - 只能点击一次
unsafeWindow.simpleGlobalVar = ();
unsafeWindow.globalObject = cloneInto(gmObject,unsafeWindow);
unsafeWindow.sayHello = exportFunction(sayHello,unsafeWindow);
console.log( ==>目标页面对象已被更改。);
});
var gmMessageStr =功能...被GM拦截,也可以使用GM_功能!
函数sayHello(){
sayHello.K =(sayHello.K || 0)+ 1;
console.log(gmMessageStr);
GM_addStyle('body {background:'+(sayHello.K%2?lime:white)+';}');
}
var gmObject = {message:对象被GM覆盖。
打开控制台并按下按钮,您将看到GM脚本能够读取和更改页面的变量和函数。
注释:
Let's say I am working with the following web page:
<html>
<body>
<span id="click">click me</span>
<script>
var hello = function() {
alert('hello');
}
document.getElementById('click').addEventListener('click', function(e) {
hello();
});
</script>
</body>
</html>
and my Greasemonkey script is:
// ==UserScript==
// @name My Script
// @include http://example.com/hello.html
// @version 1
// @grant none
// ==/UserScript==
window.hello = function() {
alert('goodbye');
}
With the Greasemonkey script disabled, clicking the #click
element on the page displays the 'hello' alert. With the script enabled, clicking the element displays the 'goodbye' alert.
Simple enough. The hello
function from the web page is being replaced by the function in the Greasemonkey script.
Now let's say I want to use a Greasemonkey API. When I set the @grant
value to a valid value other than 'none' (e.g. // @grant GM_setClipboard
) [which causes Greasemonkey to run the script as a "content script", rather than in the page's scope like with 'none'], the Greasemonkey script fails to work.
window.hello
is no longer targeting the correct object on the page.
Replacing window.hello
with unsafeWindow.hello
looks like it would work, but instead, the following error is thrown in the JS console:
Error: Permission denied to access object
How can I rewrite the Greasemonkey script while having @grant GM_setClipboard
set to target and replace the original hello
function on the page?
System information:
When you set a @grant
value other than none, Greasemonkey activates its sandbox and Greasemonkey 2.0 radically changed unsafeWindow handling.
Now, in order to create or overwrite variables in the target-page scope, you must correctly chose from a menu of techniques. EG:
To Read:
To Call:
To Write/Set:
Consider this HTML:
<button id="helloBtn">Say "Hello".</button>
And this javascript:
var simpleGlobalVar = "A simple, global var in the page scope.";
var globalObject = {Letter: "A", Number: 2};
function simpleFunction () {
console.log ("The target page's simpleFunction was called.");
}
var sayHello = function() {
console.log ('Hello.');
}
document.getElementById ('helloBtn').addEventListener ('click', function () {
sayHello ();
} );
which you can see live at this jsFiddle page.
If you install and run this Greasemonkey script against that page:
// ==UserScript==
// @name _Demonstrate accessing target-page variables with @grant values set
// @include http://fiddle.jshell.net/sepwL7n6/*/show/
// @require http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @grant GM_addStyle
// ==/UserScript==
console.log ("*** Greasemonkey script start.");
$("body").append ('<div id="gmArea">Added by Greasemonkey:<p></p></div>');
$("#gmArea > p:first").append ('<button id="gmShow">Access select target-page variables and functions</button>');
$("#gmArea > p:first").append ('<button id="gmChange">Change javascript things in the target-page scope.</button>');
$("#gmShow").click ( function () {
//-- Access things from the target-page scope:
console.log ("----------------");
console.log ("==> simpleGlobalVar is: ", unsafeWindow.simpleGlobalVar);
console.log ("==> globalObject is: ", unsafeWindow.globalObject);
console.log ("==> Calling target's simpleFunction():");
unsafeWindow.simpleFunction ();
//-- WARNING! This next technique is not robust, but works in some cases.
console.log ("==> Calling target's button's click().");
unsafeWindow.document.getElementById ('helloBtn').click ();
} );
$("#gmChange").click ( function () {
this.disabled = true; //-- Can only click once.
unsafeWindow.simpleGlobalVar = "Simple var... Intercepted by GM!";
unsafeWindow.globalObject = cloneInto (gmObject, unsafeWindow);
unsafeWindow.sayHello = exportFunction (sayHello, unsafeWindow);
console.log ("==> Target page objects were changed.");
} );
var gmMessageStr = "Function... Intercepted by GM, but also can use GM_ functions!";
function sayHello () {
sayHello.K = (sayHello.K || 0) + 1;
console.log (gmMessageStr);
GM_addStyle ('body {background: ' + (sayHello.K % 2 ? "lime" : "white") + ';}');
}
var gmObject = {message: "Object overridden by GM."};
Open the console and press the buttons and you will see that the GM script is able to read and change the page's variables and functions.
Notes:
这篇关于如何设置@grant值时如何访问`window`(目标页面)对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!