2

我想覆盖XMLHttpRequest发送,以便让我的用户脚本知道何时通过此类请求在页面上更新数据。我的覆盖代码如下所示:

var oldSend = unsafeWindow.XMLHttpRequest.prototype.send;

unsafeWindow.XMLHttpRequest.prototype.send = function(){
    console.log("notified of XHR update");
    oldSend.apply(this, arguments);
}

如果我将它注入页面(没有unsafeWindow引用)它工作正常,但我想从用户脚本范围内让它工作。 unsafeWindow适用于 Firefox,但不适用于 Chrome。所以我抓住了Brock Adams 的绝妙技巧,在 Chrome中创建了一个工作unsafeWindow

var bGreasemonkeyServiceDefined     = false;

try {
    if (typeof Components.interfaces.gmIGreasemonkeyService === "object") {
        bGreasemonkeyServiceDefined = true;
    }
}
catch (err) {
    //Ignore.
}

if ( typeof unsafeWindow === "undefined"  ||  ! bGreasemonkeyServiceDefined) {
    unsafeWindow    = ( function () {
        var dummyElem   = document.createElement('p');
        dummyElem.setAttribute ('onclick', 'return window;');
        return dummyElem.onclick ();
    } ) ();
}

但是,当我将两者结合起来时,什么也没有发生。这一切都粘贴到控制台中,但是从用户脚本运行时既没有错误也没有输出。我是不是做错了什么,或者这超出了这个技巧的能力范围?

嗯,只是尝试了一些更简单的东西,比如:unsafeWindow.document.title = 'testing';这也不起作用,所以它可能不是特定于XMLHttpRequest.

如果可能的话,我试图避免注入页面。

4

1 回答 1

1

这:

/*--- Create a proper unsafeWindow object on browsers where it doesn't exist
    (Chrome, mainly).
    Chrome now defines unsafeWindow, but does not give it the same access to
    a page's javascript that a properly unsafe, unsafeWindow has.
    This code remedies that.
*/
var bGreasemonkeyServiceDefined     = false;

try {
    if (typeof Components.interfaces.gmIGreasemonkeyService === "object") {
        bGreasemonkeyServiceDefined = true;
    }
}
catch (err) {
    //Ignore.
}

if ( typeof unsafeWindow === "undefined"  ||  ! bGreasemonkeyServiceDefined) {
    unsafeWindow    = ( function () {
        var dummyElem   = document.createElement('p');
        dummyElem.setAttribute ('onclick', 'return window;');
        return dummyElem.onclick ();
    } ) ();
}

其次是:

unsafeWindow.document.title = 'testing';

从我的测试用户脚本中工作得很好。

这些也可以按照以下unsafeWindow技巧工作:

unsafeWindow.foo = function () {
    console.log ("In foo().");
};

unsafeWindow.alert = function (s) {
    console.log ("Alert: ", s);
};

(在脚本运行的页面上,foo()在控制台中输入会产生:“ In foo(). ”。 alert()不会生成弹出窗口,但会打印到控制台。)

我不知道为什么(还)覆盖XMLHttpRequest.prototype.send不能像 Chrome 用户脚本那样工作,但我不推荐这种unsafeWindow方法。

Inject the override code. Use postMessage() (which works on Chrome as well) to communicate between the page scope and the script scope, if you don't (or can't) inject the whole script.

于 2012-06-19T04:20:07.020 回答