设置@grant值时,如何访问“窗口”(目标页面)对象?

假设我正在使用以下网页:

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

我的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.hellounsafeWindow.hello看起来像它的工作,而是下面的错误是在JS控制台抛出:

错误:拒绝访问对象的权限

@grant GM_setClipboard设置为目标并替换hello页面上的原始功能后,如何重写Greasemonkey脚本?

系统信息:

  • Windows 7 64位
  • Firefox 32.0
  • Greasemonkey 2.2

回答:

当您设置任何@grant其他值时,Greasemonkey会激活其沙箱,而Greasemonkey2.0将彻底改变unsafeWindow处理。

现在,为了在目标页面范围内创建或覆盖变量,您必须从技术菜单中正确选择。例如:

To Read:

  • 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 }

  • 这并不总是可能的。

To Call:

  • Target page sets:       function func () {console.log ('Hi');}

    GM script can call: unsafeWindow.func() //– “Hi”

To Write/Set:

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

而这个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 ();

} );

如果在该页面上安装并运行此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."};

打开控制台并按下按钮,您将看到GM脚本能够读取和更改页面的变量和功能。


笔记:

  1. 这是所有 。
  2. 对于跨平台代码和某些复杂情况,可以改用脚本注入 。但是注入的代码不能直接访问GM_函数。
  3. 请注意,这些技术仅适用于全局的javascript变量和函数。

以上是 设置@grant值时,如何访问“窗口”(目标页面)对象? 的全部内容, 来源链接: utcz.com/qa/430742.html

回到顶部