如何检查浏览器中的HTTP请求是否打开?

20

有没有一种简单的方法可以检测在浏览器窗口中是否存在活动的XMLHttpRequest?或者有多少个活动的XMLHttpRequest?也就是说,是否有一种方法可以检测我的浏览器窗口中是否有任何活动的AJAX调用?

问题的扩展:使用javascript,我能否看到是否有任何XMLHttpRequest处于打开状态?例如"window.XMLisActive()"之类的东西?

解决方案:最终编写了一个XMLHttpRequest的包装器:这里是gist


1
你所说的“active”是什么意思?能否详细说明一下,比如你是如何尝试实现这个功能的,你已经尝试了什么等等? - TheBoyan
4个回答

36

除非您编写一个包装XmlHttpRequest(或猴子补丁它)来跟踪打开的连接,否则无法检测JS中的打开连接。

这里是kidcapital的猴子补丁,不确定它是否完美,但它是一个好的开始。

  (function() {
    var oldOpen = XMLHttpRequest.prototype.open;
    window.openHTTPs = 0;
    XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
      window.openHTTPs++;
      this.addEventListener("readystatechange", function() {
          if(this.readyState == 4) {
            window.openHTTPs--;
          }
        }, false);
      oldOpen.call(this, method, url, async, user, pass);
    }
  })();

注意

这并不处理fetch或WebSockets,但在这些情况下,你可以做类似的事情。


3
我已经为此写了一份摘要,可以在这里找到:https://gist.github.com/1820380 - kidcapital
1
@kidcapital:我之前在这里发布了一个非常相似的内容,但是没有花时间完成它,所以我把它删掉了。你有看到它在发布了30秒内吗?它看起来几乎和我之前的一样。无论如何,请务必测试网络错误和abort()函数是否被调用。 - Ruan Mendes
哈哈,我没看到。网络错误仍会触发响应代码4吗?我会在abort()上再次检查。 - kidcapital
将此脚本注入到Selenium测试浏览器后,我的应用程序停止工作了。这是否阻塞了我的应用程序调用? - Karthi
尝试使用setInterval调用注入此代码,每秒记录一次变量,它可以正常工作而不会出现任何问题。因此,它不应该破坏任何应用程序。如果确实有问题,熟悉js调试的开发人员应该再次检查它... :) 我们将测试这种方法以进行测试自动化,以便能够知道当前是否没有打开任何ajax请求,或者在所有请求都已完成时进行通知... - Martin
显示剩余2条评论

3
你可以使用 FireBug 进行相关操作。

在此输入图片描述


或者任何其他的浏览器开发环境。https://dev59.com/C1LTa4cB1Zd3GeqPcavh#4445828 - Ruan Mendes

2

我尝试了@juan-mendes的解决方案,但是出现了错误:ERROR Error Code: undefined Message: Failed to set the 'responseType' property on 'XMLHttpRequest': The response type cannot be changed for synchronous requests made from a document.在我的Angular应用程序中。原因是async参数默认为true,但当缺少该参数时,此补丁会传递undefined,而这相当于false。带有此小更改的代码对我有效:

(function() {
        var oldOpen = XMLHttpRequest.prototype.open;
        window.openHTTPs = 0;
        XMLHttpRequest.prototype.open = function(method, url, async = true, user = null, pass = null) {
            window.openHTTPs++;
            this.addEventListener("readystatechange", function() {
                if(this.readyState == 4) window.openHTTPs--;
            }, false);
            oldOpen.call(this, method, url, async, user, pass);
        }
    })()

1
通过使用jQuery,您可以使用全局事件处理程序.ajaxStart().ajaxComplete()来跟踪是否有打开的请求。
在ajaxStart上设置一个全局变量,并在ajaxComplete上重置它即可完成任务。

这里假设您正在使用jQuery的.ajax方法。但是如果您没有jQuery库呢? - kidcapital
2
这就是我的答案提到的,如果你有一个 XmlHttpRequest 的包装器,那么很容易实现(如果你的包装器支持它的话)。如果你没有 jQuery,你可以开始使用它,或者编写自己的包装器。 - Ruan Mendes
正确的配对是ajaxSend和ajaxComplete(请查看文档) - Rushabh Mehta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接