Javascript 设置@grant值时如何访问“窗口”(目标页)对象?
假设我正在使用以下网页:Javascript 设置@grant值时如何访问“窗口”(目标页)对象?,javascript,firefox,greasemonkey,Javascript,Firefox,Greasemonkey,假设我正在使用以下网页: 点击我 var hello=function(){ 警惕(“你好”); } document.getElementById('click')。addEventListener('click',函数(e){ 你好; }); 我的Greasemonkey脚本是: // ==UserScript== // @name My Script // @include http://example.com/hello.html // @version
点击我
var hello=function(){
警惕(“你好”);
}
document.getElementById('click')。addEventListener('click',函数(e){
你好;
});
我的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脚本中的函数替换
现在让我们假设我想使用Greasemonkey API。当我将@grant
值设置为“none”以外的有效值(例如/@grant GM_setClipboard
)[这会导致Greasemonkey以“内容脚本”的形式运行脚本,而不是像“none”一样在页面的作用域中运行脚本],Greasemonkey脚本无法工作
window.hello
不再针对页面上的正确对象
将window.hello
替换为unsafeWindow.hello
看起来是可行的,但是JS控制台中会抛出以下错误:
错误:访问对象的权限被拒绝
在将@grant GM_setClipboard
设置为target并替换页面上原来的hello
函数时,如何重写Greasemonkey脚本
系统信息:
- Windows 7 64位
- Firefox32.0
- Greasemonkey 2.2
@grant
值时,Greasemonkey将激活其沙箱并启动
现在,为了在目标页面范围中创建或覆盖变量,必须从技术菜单中正确选择。例如:
全文如下:
- 一个简单变量:
Target page sets: var foo = "bar"; GM script can read: unsafeWindow.foo //-- "bar"
Target page sets: var obj = {A: 1}; GM script can read: unsafeWindow.obj //-- Object { A: 1 }
Target page sets: function func () {console.log ('Hi');} GM script can call: unsafeWindow.func() //-- "Hi"
unsafeWindow.foo = "Apple";
var gmObject = {X: "123"}; unsafeWindow.obj = cloneInto (gmObject, unsafeWindow);
function gmFunc () { console.log ("Lorem ipsum"); //-- Can use GM_ functions in here! :) } unsafeWindow.func = exportFunction (gmFunc, unsafeWindow);
- 一个简单的对象:
Target page sets: var foo = "bar"; GM script can read: unsafeWindow.foo //-- "bar"
Target page sets: var obj = {A: 1}; GM script can read: unsafeWindow.obj //-- Object { A: 1 }
Target page sets: function func () {console.log ('Hi');} GM script can call: unsafeWindow.func() //-- "Hi"
unsafeWindow.foo = "Apple";
var gmObject = {X: "123"}; unsafeWindow.obj = cloneInto (gmObject, unsafeWindow);
function gmFunc () { console.log ("Lorem ipsum"); //-- Can use GM_ functions in here! :) } unsafeWindow.func = exportFunction (gmFunc, unsafeWindow);
- 复杂对象:这并不总是可能的
- 一个简单的函数:
Target page sets: var foo = "bar"; GM script can read: unsafeWindow.foo //-- "bar"
Target page sets: var obj = {A: 1}; GM script can read: unsafeWindow.obj //-- Object { A: 1 }
Target page sets: function func () {console.log ('Hi');} GM script can call: unsafeWindow.func() //-- "Hi"
unsafeWindow.foo = "Apple";
var gmObject = {X: "123"}; unsafeWindow.obj = cloneInto (gmObject, unsafeWindow);
function gmFunc () { console.log ("Lorem ipsum"); //-- Can use GM_ functions in here! :) } unsafeWindow.func = exportFunction (gmFunc, unsafeWindow);
- 复杂函数:
- 一个简单变量:
Target page sets: var foo = "bar"; GM script can read: unsafeWindow.foo //-- "bar"
Target page sets: var obj = {A: 1}; GM script can read: unsafeWindow.obj //-- Object { A: 1 }
Target page sets: function func () {console.log ('Hi');} GM script can call: unsafeWindow.func() //-- "Hi"
unsafeWindow.foo = "Apple";
var gmObject = {X: "123"}; unsafeWindow.obj = cloneInto (gmObject, unsafeWindow);
function gmFunc () { console.log ("Lorem ipsum"); //-- Can use GM_ functions in here! :) } unsafeWindow.func = exportFunction (gmFunc, unsafeWindow);
- 一个简单的对象:
Target page sets: var foo = "bar"; GM script can read: unsafeWindow.foo //-- "bar"
Target page sets: var obj = {A: 1}; GM script can read: unsafeWindow.obj //-- Object { A: 1 }
Target page sets: function func () {console.log ('Hi');} GM script can call: unsafeWindow.func() //-- "Hi"
unsafeWindow.foo = "Apple";
var gmObject = {X: "123"}; unsafeWindow.obj = cloneInto (gmObject, unsafeWindow);
function gmFunc () { console.log ("Lorem ipsum"); //-- Can use GM_ functions in here! :) } unsafeWindow.func = exportFunction (gmFunc, unsafeWindow);
- 一个简单的函数:
Target page sets: var foo = "bar"; GM script can read: unsafeWindow.foo //-- "bar"
Target page sets: var obj = {A: 1}; GM script can read: unsafeWindow.obj //-- Object { A: 1 }
Target page sets: function func () {console.log ('Hi');} GM script can call: unsafeWindow.func() //-- "Hi"
unsafeWindow.foo = "Apple";
var gmObject = {X: "123"}; unsafeWindow.obj = cloneInto (gmObject, unsafeWindow);
function gmFunc () { console.log ("Lorem ipsum"); //-- Can use GM_ functions in here! :) } unsafeWindow.func = exportFunction (gmFunc, unsafeWindow);
考虑以下HTML:
<button id="helloBtn">Say "Hello".</button>
你可以在现场看到
如果在该页面上安装并运行此Greasemonkey脚本:
// ==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."};
/==UserScript==
//@name\u演示如何访问设置了@grant值的目标页面变量
//@包括http://fiddle.jshell.net/sepwL7n6/*/展示/
//@需要http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
//@grant GM_addStyle
//==/UserScript==
console.log(“***Greasemonkey脚本开始”);
$(“body”).append('由Greasemonkey添加:);
$(“#gmArea>p:first”).append('Access select target page variables and functions');
$(“#gmArea>p:first”).append('更改目标页面范围中的javascript内容');
$(“#gmShow”)。单击(函数(){
//--从目标页面范围访问内容:
console.log(“------------------------------”);
console.log(“=>simpleGlobalVar为:”,unsafeWindow.simpleGlobalVar);
console.log(“=>globalObject为:”,unsafeWindow.globalObject);
console.log(“==>调用目标的simpleFunction():”;
unsafeWindow.simpleFunction();
//--警告!下一种技术不可靠,但在某些情况下有效。
console.log(“==>调用目标按钮的click()”;
unsafeWindow.document.getElementById('helloBtn')。单击();
} );
$(“#gmChange”)。单击(函数(){
this.disabled=true;//--只能单击一次。
unsafeWindow.simpleGlobalVar=“简单变量…被GM截获!”;
unsafeWindow.globalObject=cloneInto(gmObject,unsafeWindow);
unsafeWindow.sayHello=exportFunction(sayHello,unsafeWindow);
console.log(“==>目标页面对象已更改。”);
} );
var gmMessageStr=“函数…被GM截获,但也可以使用GM_u函数!”;
函数sayHello(){
sayHello.K=(sayHello.K | | 0)+1;
console.log(gmMessageStr);
GM_addStyle('body{background:'+(sayHello.K%2?):“white”)+';});
}
var gmObject={消息:“对象被GM.覆盖”};
打开控制台并按下按钮,您将看到GM脚本能够读取和更改页面的变量和函数
注:
GM
函数将代码包装在lambda函数中,如下所示:
(function(window){ // and more arguments if you need it
console.log(window); // here, should be the real 'window'
})(window.unsafeWindow)
你可能想看看新的
unsafeWindow
行为是否真的来自Firefox30,就像它在中所说的那样?据推测,GM 2.0中的相关更改与确保新API可供GM脚本使用有关,并且可能是GM自己正确地使用了这些API,而不是依赖于旧的行为。@SamB,不完全如此。请注意,该博客条目是关于SDK的,而不是关于Firefox的。通用汽车不使用SDK,也不必进行当时所做的更改。目前尚不清楚未来计划对FF的更改是否最终会迫使进行更改,但新方法更好,因为它允许更容易地将GM功能集成到目标页面代码中(这是一种危险的做法)。