在正确使用@grant时,在Greasemonkey中拦截XMLHttpRequest

时间:2016-03-31 14:36:32

标签: javascript ajax xmlhttprequest greasemonkey

所以我的目标是劫持所有XMLHttpRequest个回复,并在我的脚本范围内对它们做些什么。但是,因为我@grant我必须使用unsafeWindow 的东西不能轻易做到。 (我不知道为什么,但我无法改变unsafeWindow.XMLHttpRequest.prototype.open。没有错误,但XMLHttpRequest根本没有工作。)所以我最终得到了这段代码:

// ==UserScript==
// @name        a
// @include     *
// @version     1
// @grant       GM_xmlhttpRequest
// ==/UserScript==

realProcess = function(xhr) {
    // do something
}

function hijackAjax(process) {
    if(typeof process != "function") {
        process = function(e){ console.log(e); };
    }
    window.addEventListener("hijack_ajax", function(event) {
        process(event.detail);
    }, false);
    function injection() {
        var open = XMLHttpRequest.prototype.open;
        XMLHttpRequest.prototype.open = function() {
            this.addEventListener("load", function() {
                window.dispatchEvent(new CustomEvent("hijack_ajax", {detail: this}));
            }, false);
            open.apply(this, arguments);
        };
    }
    window.setTimeout("(" + injection.toString() + ")()", 0);
}
hijackAjax(realProcess);

我的问题是:可以做得更好/更快/更优雅吗?

编辑:根据提示更新了代码。

1 个答案:

答案 0 :(得分:1)

解决方案取决于您希望如何进行互动。您可以将所有逻辑注入站点的范围,但是,如果您想要进行交互,则在用户脚本的范围和站点范围之间存在障碍。在两个范围之间交换数据并非易事。 unsafeWindow是邪恶的,避免使用。在setTimeout(String)内将逻辑作为要评估的字符串注入,以便在站点范围内执行。如果需要在特权范围内与用户脚本进行交互,请使用window.dispatchEvent(new CustomEvent('eventname', {'detail': scalarData}));设置消息传递系统。您将无法使用其他权限传输在作用域中声明的复杂数据类型。