JavaScript:检测AJAX请求

时间:2012-05-28 10:55:44

标签: javascript ajax request call

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

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

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

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

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

4 个答案:

答案 0 :(得分:31)

以下是一些代码(通过粘贴到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));
    };


})();

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

  

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

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

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

答案 1 :(得分: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);
}

我没有测试它,但它看起来或多或少都很好。

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

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

答案 2 :(得分:17)

尝试一下。检测Ajax响应,然后使用XMLHttpRequest propoerties readyState&添加条件。如果响应状态= 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;

修改自: Monitor all JavaScript events in the browser console

答案 3 :(得分:2)

该问题的现代(截至 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>

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


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