使用用户脚本捕获页面xmlhttp请求

发布于 2021-01-31 17:38:27

我有一个用户脚本(适用于chrome和FF),该脚本向页面添加了重要功能,但最近由于开发人员向页面添加了一些AJAX而被破坏了。我想修改脚本以侦听xmlhttp请求的页面,以便可以基于responseText页面接收的JSON格式动态更新添加的内容。

搜索显示了许多应该工作的功能,这些功能在控制台中运行时也可以工作。但是,它们在用户脚本的上下文中什么也不做。

(function(open) {

    XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {

        this.addEventListener("readystatechange", function() {
            console.log(this.readyState);
        }, false);

        open.call(this, method, url, async, user, pass);
    };

})(XMLHttpRequest.prototype.open);

它可以在控制台中完美地工作,我可以更改this.readyStatethis.responseText它,并且效果很好(尽管在脚本中,我将需要它将JSON数据转换为对象,然后让我在用户脚本中对其进行操作。而不仅仅是写入控制台)
。但是,如果我将其粘贴到用户脚本中,则不会发生任何事情。用户脚本中的事件处理程序似乎未检测到页面上的xmlhttp请求。

进行请求的页面正在使用jquery $ .get()函数,如果这可能与它有关。虽然我不认为这样。

我无法想象没有办法,似乎在AJAX页面上运行的任何用户脚本都需要此功能。

关注者
0
被浏览
96
1 个回答
  • 面试哥
    面试哥 2021-01-31
    为面试而生,有面试问题,就找面试哥。

    由于页面使用$.get(),因此拦截请求甚至更加容易。使用ajaxSuccess()

    这将在Greasemonkey(Firefox)脚本中起作用:
    片段1:

    unsafeWindow.$('body').ajaxSuccess (
        function (event, requestData)
        {
            console.log (requestData.responseText);
        }
    );
    

    假设页面以普通方式($定义等)使用jQuery 。

    这应该可以在Chrome用户脚本(以及Greasemonkey)中运行:
    片段2:

    function interceptAjax () {
        $('body').ajaxSuccess (
            function (event, requestData)
            {
                console.log (requestData.responseText);
            }
        );
    }
    
    function addJS_Node (text, s_URL, funcToRun) {
        var D                                   = document;
        var scriptNode                          = D.createElement ('script');
        scriptNode.type                         = "text/javascript";
        if (text)       scriptNode.textContent  = text;
        if (s_URL)      scriptNode.src          = s_URL;
        if (funcToRun)  scriptNode.textContent  = '(' + funcToRun.toString() + ')()';
    
        var targ    = D.getElementsByTagName('head')[0] || D.body || D.documentElement;
        targ.appendChild (scriptNode);
    }
    
    addJS_Node (null, null, interceptAjax);
    



    回覆:

    “但是如何将这些数据保存到脚本中呢?…(这样我就可以)稍后在脚本中使用这些数据。”

    这适用于Greasemonkey(Firefox);
    它也可能在Chrome的Tampermonkey中起作用
    代码段3:

    function myAjaxHandler (requestData) {
        console.log ('myAjaxHandler: ', requestData.responseText);
    }
    
    unsafeWindow.$('body').ajaxSuccess (
        function (event, requestData) {
            myAjaxHandler (requestData);
        }
    );
    

    但是, 如果不是 这样,则无法通过设计在Chrome用户脚本和目标页面之间轻松地共享JS信息。

    通常,您要做的是注入整个用户脚本,以便所有内容都在页面范围内运行。像这样:
    片段4:

    function scriptWrapper () {
    
        //--- Intercept Ajax
        $('body').ajaxSuccess (
            function (event, requestData) {
                doStuffWithAjax (requestData);
            }
        );
    
        function doStuffWithAjax (requestData) {
            console.log ('doStuffWithAjax: ', requestData.responseText);
        }
    
        //--- DO YOUR OTHER STUFF HERE.
        console.log ('Doing stuff outside Ajax.');
    }
    
    function addJS_Node (text, s_URL, funcToRun) {
        var D                                   = document;
        var scriptNode                          = D.createElement ('script');
        scriptNode.type                         = "text/javascript";
        if (text)       scriptNode.textContent  = text;
        if (s_URL)      scriptNode.src          = s_URL;
        if (funcToRun)  scriptNode.textContent  = '(' + funcToRun.toString() + ')()';
    
        var targ    = D.getElementsByTagName('head')[0] || D.body || D.documentElement;
        targ.appendChild (scriptNode);
    }
    
    addJS_Node (null, null, scriptWrapper);
    


推荐阅读
知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看