JavaScript:检测AJAX请求

myt*_*lon 31 javascript ajax call request

有没有办法在使用通用JavaScript(而不是框架)的网页上检测全局AJAX调用(特别是响应)?

我已经在StackOverflow上查看了" JavaScript检测AJAX事件 " 的问题,并尝试将接受的答案代码修补到我的应用程序中,但它没有用.我之前从未对AJAX做过任何事情,我不知道修改它是否有效.

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

if (ajax.response == "certainResponseType"){
    //Code
}
Run Code Online (Sandbox Code Playgroud)

, 例如.

更新: 似乎我应该澄清我不是在尝试发送请求 - 我正在开发一个内容脚本,我需要能够检测到网页的AJAX请求(不是我自己的),所以我可以执行一个检测到响应时起作用.

Omn*_*Omn 33

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

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


})();
Run Code Online (Sandbox Code Playgroud)

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

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

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

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


小智 22

试一试.检测Ajax响应,然后我使用XMLHttpRequest propoerties readyState&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;
Run Code Online (Sandbox Code Playgroud)

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


fre*_*ish 21

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

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);
}
Run Code Online (Sandbox Code Playgroud)

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

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

编辑:现在(2018年初),新的fetch API变得更加复杂.fetch必须以类似的方式覆盖全局函数.


Dai*_*Dai 10

该问题的现代(截至 2021 年 4 月)答案是使用PerformanceObserver它来观察XMLHttpRequest请求和fetch()请求:

<!-- Place this at the top of your page's <head>: -->
<script type="text/javascript">
var myRequestLog = []; // Using `var` (instead of `let` or `const`) so it creates an implicit property on the (global) `window` object so you can easily access this log from anywhere just by using `window.myRequestLog[...]`.
function onRequestsObserved( batch ) {
    myRequestLog.push( ...batch.getEntries() );
}
var requestObserver = new PerformanceObserver( onRequestsObserved );
requestObserver.observe( { type: 'resource' /*, buffered: true */ } );
</script>
Run Code Online (Sandbox Code Playgroud)

我在页面中使用上面的代码片段来记录请求,以便我可以在全局回调中将它们报告给母舰window.addEventListenr('error', ... )


  • batch.getEntries()函数返回一个 DOM 对象数组PerformanceResourceTiming(因为我们只监听type: 'resource',否则它将返回一个不同类型对象的数组)。
  • 每个PerformanceResourceTiming对象都有有用的属性,例如:
    • initiatorType属性可以是:
      • 如果请求是由元素引起的,则为 HTML 元素名称(标记名称):
        • 'link'- 请求来自<link>页面中的元素。
        • 'script'- 请求是加载一个<script>.
        • 'img'- 请求是加载一个<img />元素。
        • ETC
      • 'xmlhttprequest'- 请求是由XMLHttpRequest调用引起的。
      • 'fetch'- 请求是由fetch()呼叫引起的。
    • name- 资源/请求的 URI。(如果有重定向,我不确定这是原始请求 URI 还是最终请求 URI)。
    • startTime警告:PerformanceObserver.observe()这实际上是请求启动后调用的时间。
    • duration警告:PerformanceObserver.observe()这实际上是请求完成后调用的时间:它不仅仅是请求的持续时间。要获得“真实”持续时间,您需要startTime从中减去duration
    • transferSize:响应中的字节数。