Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ajax/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 以正确的方式使用@grant时拦截Greasemonkey中的XMLHttpRequest_Javascript_Ajax_Xmlhttprequest_Greasemonkey - Fatal编程技术网

Javascript 以正确的方式使用@grant时拦截Greasemonkey中的XMLHttpRequest

Javascript 以正确的方式使用@grant时拦截Greasemonkey中的XMLHttpRequest,javascript,ajax,xmlhttprequest,greasemonkey,Javascript,Ajax,Xmlhttprequest,Greasemonkey,因此,我的目标是劫持所有XMLHttpRequest响应,并在我的脚本范围内对它们进行处理。但由于我@grant我不得不使用unsafeWindow的一些东西不能用简单的方式完成。(我不知道为什么,但我无法更改unsafeWindow.XMLHttpRequest.prototype.open。没有错误,但XMLHttpRequest根本不起作用。)因此我最终得到了以下代码: // ==UserScript== // @name a // @include * // @ve

因此,我的目标是劫持所有
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);
我的问题是:能做得更好/更快/更优雅吗


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

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

!您可以在
CustomEvent
中发送整个xhr对象,这与
窗口中不同。postMessage
。使用
setTimeout(String)
注入代码而不是将
标记附加到DOM中有什么好处吗?当然,除了少写两行之外,我不能100%确定当授予特权API时,浏览器如何处理从GM上下文附加的脚本。通过
setTimeout
执行字符串化代码是在站点上下文中声明某些内容的一种方法。您可以通过运行一个试图执行注入代码的页面来测试它。如果它能工作,我看不到任何缺陷,除了当你在
(function(){…})(
)中通过
setTimeout
执行代码时,页面很难找到一些操作,例如,一个不允许用户脚本的游戏站点。当
dispatchEvent
返回时,检查您对GM的xhr对象的操作是否仍然存在于站点上下文中。否则,您可能必须传输标量消息数据,告诉在站点上下文中运行的函数要做什么,例如JSON字符串,以便可以在站点上下文中重建对象。当GM脚本被授予任何权限时,不允许站点访问GM上下文中声明的数据或执行代码。我将坚持使用
setTimeout
then.:)修改脚本后,我可以设置请求头、读取响应头、文本、状态等,甚至可以中止xhr。我应该将其作为新答案发布还是编辑问题?