JavaScript:检测 AJAX 请求

IT技术 javascript ajax request call
2021-02-25 02:18:37

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

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

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

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

, 例如。

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

4个回答

这是一些用于捕获和记录或以其他方式处理 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));
    };


})();

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

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

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

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

在这种情况下,有没有办法找出发送的 URL?
2021-05-07 02:18:37

试试这个。检测 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;

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

这对我有用。对 stackoverflow 的请求进行了测试,并可靠地检测到完整状态。然而,从怪异的接受答案中剪下的片段对我不起作用。
2021-05-04 02:18:37
这正是我所需要的!
2021-05-16 02:18:37

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

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 年初)使用新的 fetch API变得更加复杂全局fetch函数也必须以类似的方式被覆盖。

嗯.. 仍然没有做任何事情。:|
2021-04-20 02:18:37
(1) 我没有积极使用框架(事实上,我正在积极尝试不这样做),但 Chrome 的框架可能会干扰。(2) 网站的内容已加载,所以它应该已经结束。(3) 是的,我注意到并改变了它。我现在就试试你的建议。:)
2021-04-25 02:18:37
@BenHooper 因为它目前什么都不做 - 您需要在onreadystatechange处理程序中添加自己的代码它对我有用(刚刚测试过)。你在使用框架吗?
2021-05-03 02:18:37
抱歉,我应该提到我用一个简单的alert("AJAX");. 还是一无所获。另外,我现在已经用更多信息更新了我的问题。
2021-05-08 02:18:37
@BenHooper 有三种可能性:(1) 框架覆盖了 XMLHttpRequest 对象(如果是,那么我担心你无能为力:( 除非你覆盖框架 :] ),(2)AJAX 请求没有最后,(3) 您正在尝试跨域 AJAX(但随后您会在控制台中看到错误)。尝试将其放在alert外面if看看会发生什么(顺便说一句:我的代码中有一个错字:最后一行有三重p) .
2021-05-15 02:18:37

对这个问题的现代(截至 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()函数返回一个 DOMPerformanceResourceTiming对象数组(因为我们只监听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()是请求完成后被调用的时间它不仅仅是请求的持续时间为了得到“真正的”时间您需要减去startTimeduration
    • transferSize:响应中的字节数。