【问题标题】:capture a pages xmlhttp requests with a userscript使用用户脚本捕获页面 xmlhttp 请求
【发布时间】:2011-11-24 15:56:23
【问题描述】:

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

搜索发现了许多应该可以工作的功能,并且在控制台中运行时也可以工作。但是,它们不会从用户脚本的上下文中执行任何操作。

(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);

发件人:How can I intercept XMLHttpRequests from a Greasemonkey script?

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

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

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

【问题讨论】:

    标签: ajax xmlhttprequest userscripts


    【解决方案1】:

    由于页面使用$.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:
    Snippet 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);
    

    【讨论】:

    • 但是我如何将这些数据获取到脚本中呢?您向页面添加了一个函数,而不是让用户脚本抓取数据。它可以写入控制台,但我不能在脚本后面使用数据。除非我错过了什么?
    • 查看更新后的答案。对于 GM 脚本来说,这是小菜一碟。对于 Chrome 用户脚本,传统的方法是注入整个脚本。
    • 这让我 "Object [object DOMWindow] has no method '$'" 我想这更多是关于 jquery 的问题?
    • 哪个 sn-p 让你明白了?如果它是最后一个 sn-p(带有scriptWrapper),那么,是的,非标准的 jQuery 是可疑的。链接到目标页面。
    • 不,您编辑的第一个。该页面无法链接,因为它需要一个帐户才能查看。运行 jquery 的脚本位于一个独立的 .js 文件中,顺便说一句,尽管我认为这没有什么不同。问题是他们在那个脚本中使用了“$”,所以应该定义它。
    猜你喜欢
    • 1970-01-01
    • 2021-05-27
    • 2019-11-25
    • 1970-01-01
    • 1970-01-01
    • 2018-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多