JavaScript:检测 AJAX 请求
Posted
技术标签:
【中文标题】JavaScript:检测 AJAX 请求【英文标题】:JavaScript: Detect AJAX requests 【发布时间】:2012-06-02 18:01:09 【问题描述】:有没有什么方法可以使用通用 javascript(不使用框架)检测网页上的全局 AJAX 调用(尤其是响应)?
我已经在 *** 上查看了问题“JavaScript detect an AJAX event”,并尝试将接受的答案代码修补到我的应用程序中,但没有奏效。我之前从未使用 AJAX 做过任何事情,所以我不知道如何修改它以使其正常工作。
我不需要任何花哨的东西,我只需要检测所有(实际上是具体的,但我必须先检测所有并从那里开始)AJAX 响应并将它们修补到 IF 语句中以供使用。所以,最终,我想要这样的东西:
if (ajax.response == "certainResponseType")
//Code
,例如。
更新: 看来我应该澄清一下,我不是在尝试发送请求 - 我正在开发内容脚本,并且我需要能够检测网页的 AJAX 请求(不是我自己的),所以我可以在检测到响应时执行一个函数。
【问题讨论】:
在我最终来到这里之前,我总是广泛地用谷歌搜索这些东西。我什至在发布之前检查了 *** 本身。 关于您的更新我认为这在浏览器扩展之外是不可能的。 你不认为浏览器扩展不可能吗?我不明白为什么不,请注意。它只运行标准的 JavaScript。 如果我没听错的话:我想说的是,我认为只有可以在浏览器扩展中实现。 那么应该没有问题,因为内容脚本是浏览器扩展的一部分。 (对不起,我上次评论的混乱性质。我编辑了它,忘了删除第一个“不”) 【参考方案1】:这里有一些代码(通过粘贴到 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 确实)。或者他们可以覆盖发送方法(但这不太可能)。 所以这是部分解决方案。
因为它不依赖未更改的“onreadystatechange”回调,而是监控“readyState”本身。
我从这里改编了答案:https://***.com/a/7778218/1153227
【讨论】:
这种情况下有没有办法查出发送的URL?【参考方案2】:试试这个。检测 Ajax 响应,然后我添加了一个条件,使用 XMLHttpRequest 属性 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】:这可能有点棘手。这个怎么样?
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),它可能不起作用,因为它们可能会在调用 send
后覆盖 onreadystatechange
(我认为 jQuery 可以)。或者他们可以覆盖send
方法(但这不太可能)。所以这是部分解决方案。
编辑:如今(2018 年初)the new fetch API 变得更加复杂。全局fetch
函数也必须以类似方式覆盖。
【讨论】:
@BenHooper 因为它目前不执行任何操作 - 您需要在onreadystatechange
处理程序中添加您自己的代码。它对我有用(刚刚测试过)。你在使用框架吗?
对不起,我应该提到我用简单的alert("AJAX");
替换了评论。还是一无所获。另外,我现在已经用更多信息更新了我的问题。
@BenHooper 有三种可能性:(1)框架覆盖 XMLHttpRequest 对象(如果是这样,那么我担心你无能为力:(除非你覆盖框架:]), (2) AJAX 请求没有结束,(3) 您正在尝试跨域 AJAX(但随后您会在控制台中看到错误)。尝试将 alert
放在 if
之外,看看会发生什么(顺便说一句:我的代码中有一个错字:最后一行有三倍p
)。
(1) 我没有积极使用框架(事实上,我正在积极尝试不这样做),但 Chrome 的框架可能会干扰。 (2) 网站的内容已经加载,所以应该已经结束。 (3) 是的,我注意到并改变了它。我现在就试试你的建议。 :)
嗯.. 仍然没有做任何事情。 :|【参考方案4】:
该问题的现代(截至 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>
我在我的页面中使用上面的 sn-p 来记录请求,以便我可以在我的全局 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()
以来的时间:这不仅仅是请求的持续时间。要获得“真实”持续时间,您需要从 duration
中减去 startTime
。
transferSize
:响应中的字节数。
【讨论】:
以上是关于JavaScript:检测 AJAX 请求的主要内容,如果未能解决你的问题,请参考以下文章