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

var oldSend = unsafeWindow.XMLHttpRequest.prototype.send;

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


如果我将其注入页面(不带unsafeWindow引用),则可以正常工作,但我想从userscript范围获得此功能。 unsafeWindow在Firefox中适用,但在Chrome中不适用。所以我抓住了Brock Adams' nifty trick to create a working unsafeWindow in Chrome

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

我试图尽可能避免注入页面。

最佳答案

这个:

/*--- 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()不会生成弹出窗口,而是会打印到控制台。)

我不知道为什么(cc)覆盖XMLHttpRequest.prototype.send不能像Chrome用户脚本那样工作,但是我仍然不建议使用unsafeWindow方法。

注入替代代码。如果您不(或无法)注入整个脚本,请使用postMessage()(同样适用于Chrome浏览器)在页面范围和脚本范围之间进行通信。

关于javascript - 为什么Chrome unsafeWindow技巧不支持XMLHttpRequest发送覆盖?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11093759/

10-15 15:10