JavaScript:检测 AJAX 请求

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10783463/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 02:54:43  来源:igfitidea点击:

JavaScript: Detect AJAX requests

javascriptajaxrequestcall

提问by mythofechelon

Is there any way to detect global AJAX calls (particularly responses) on a web page with generic JavaScript (not with frameworks)?

有什么方法可以使用通用 JavaScript(而不是框架)在网页上检测全局 AJAX 调用(特别是响应)?

I've already reviewed the question "JavaScript detect an AJAX event", here on StackOverflow, and tried patching in the accepted answer's code into my application but it didn't work. I've never done anything with AJAX before either so, I don't know enough to modify it to work.

我已经在 StackOverflow 上查看了问题“ JavaScript 检测到 AJAX 事件”,并尝试将接受的答案的代码修补到我的应用程序中,但没有奏效。我之前也从来没有用 AJAX 做过任何事情,所以我不知道如何修改它才能工作。

I don't need anything fancy, I just need to detect all (specific, actually, but I'd have to detect all first and go from there) AJAX responses and patch them into an IF statement for use. So, eventually, I'd like something like:

我不需要任何花哨的东西,我只需要检测所有(实际上是特定的,但我必须首先检测所有并从那里开始)AJAX 响应并将它们修补到 IF 语句中以供使用。所以,最终,我想要这样的东西:

if (ajax.response == "certainResponseType"){
    //Code
}

, for example.

, 例如。

Update:It seems I should clarify that I'm not trying to send a request - I'm developing a content script and I need to be able to detectthe web page's AJAX requests (not make my own), so I can execute a function when a response is detected.

更新:看来我应该澄清一下,我不是在尝试发送请求——我正在开发一个内容脚本,我需要能够检测网页的 AJAX 请求(不是我自己的),所以我可以执行一个检测到响应时的功能。

回答by Omn

Here's some code (tested by pasting into Chrome 31.0.1650.63's console) for catching and logging or otherwise processing ajax requests and their responses:

这是一些用于捕获和记录或以其他方式处理 ajax 请求及其响应的代码(通过粘贴到 Chrome 31.0.1650.63 的控制台进行测试):

(function() {
    var proxied = window.XMLHttpRequest.prototype.send;
    window.XMLHttpRequest.prototype.send = function() {
        console.log( arguments );
        //Here is where you can add any code to process the request. 
        //If you want to pass the Ajax request object, pass the 'pointer' below
        var pointer = this
        var intervalId = window.setInterval(function(){
                if(pointer.readyState != 4){
                        return;
                }
                console.log( pointer.responseText );
                //Here is where you can add any code to process the response.
                //If you want to pass the Ajax request object, pass the 'pointer' below
                clearInterval(intervalId);

        }, 1);//I found a delay of 1 to be sufficient, modify it as you need.
        return proxied.apply(this, [].slice.call(arguments));
    };


})();

This code solves the above issue with the accepted answer:

此代码使用已接受的答案解决了上述问题:

Note that it may not work if you use frameworks (like jQuery), because they may override onreadystatechange after calling send (I think jQuery does). Or they can override send method (but this is unlikely). So it is a partial solution.

请注意,如果您使用框架(如 jQuery),它可能不起作用,因为它们可能会在调用 send 后覆盖 onreadystatechange(我认为 jQuery 可以)。或者他们可以覆盖 send 方法(但这不太可能)。所以这是一个部分的解决方案。

Because it does not rely on the 'onreadystatechange' callback being un-changed, but monitors the 'readyState' itself.

因为它不依赖于未更改的 'onreadystatechange' 回调,而是监视 'readyState' 本身。

I adapted the answer from here: https://stackoverflow.com/a/7778218/1153227

我从这里改编了答案:https: //stackoverflow.com/a/7778218/1153227

回答by mmguy

Gives this a try. Detects Ajax responses, then I added a conditional using the XMLHttpRequest propoerties readyState & status to run function if response status = OK

试试这个。检测 Ajax 响应,然后我使用 XMLHttpRequest 属性 readyState & status 添加一个条件以运行函数 if response status = OK

var oldXHR = window.XMLHttpRequest;

function newXHR() {
    var realXHR = new oldXHR();
    realXHR.addEventListener("readystatechange", function() {
        if(realXHR.readyState==4 && realXHR.status==200){
            afterAjaxComplete() //run your code here
        }
    }, false);
    return realXHR;
}
window.XMLHttpRequest = newXHR;

Modified from: Monitor all JavaScript events in the browser console

修改自: 在浏览器控制台监控所有 JavaScript 事件

回答by freakish

This can be a bit tricky. How about this?

这可能有点棘手。这个怎么样?

var _send = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function() {

    /* Wrap onreadystaechange callback */
    var callback = this.onreadystatechange;
    this.onreadystatechange = function() {             
         if (this.readyState == 4) {
             /* We are in response; do something,
                like logging or anything you want */
         }
         callback.apply(this, arguments);
    }

    _send.apply(this, arguments);
}

I didn't test it, but it looks more or less fine.

我没有测试它,但它看起来或多或少不错。

Note that it may not work if you use frameworks (like jQuery), because they may override onreadystatechangeafter calling send(I think jQuery does). Or they can override sendmethod (but this is unlikely). So it is a partial solution.

请注意,如果您使用框架(如 jQuery),它可能不起作用,因为它们可能会onreadystatechange在调用后覆盖send(我认为 jQuery 可以)。或者他们可以覆盖send方法(但这不太可能)。所以这是一个部分的解决方案。

EDIT:Nowadays (the begining of 2018) this gets more complicated with the new fetch API. Global fetchfunction has to be overridden as well in a similar manner.

编辑:如今(2018 年初)使用新的 fetch API变得更加复杂。全局fetch函数也必须以类似的方式被覆盖。