You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自动化测试中如何用JavaScript判断页面AJAX请求是否在执行?

检测页面中活跃的AJAX请求,等待所有异步操作完成

针对你遇到的痛点——document.readyState === "complete"只能判断初始页面资源加载完成,没法覆盖AJAX这类异步请求的情况,这里有几个实用方案帮你检测活跃AJAX请求,确保所有页面操作(包括异步更新)完成后再执行后续测试步骤:

方法1:全局重写AJAX相关方法(通用方案)

这个方法能覆盖绝大多数AJAX场景,包括原生XMLHttpRequest、fetch,以及基于它们封装的库(比如axios、jQuery.ajax)。核心思路是维护一个计数器,跟踪当前活跃的请求数:

实现代码:

// 初始化活跃请求计数器
let activeAjaxCount = 0;

// 重写XMLHttpRequest,捕获请求发起与结束
const originalXHROpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url, ...args) {
  activeAjaxCount++;
  // 监听请求完成(成功、失败、中断都算结束)
  this.addEventListener('loadend', () => {
    activeAjaxCount--;
  });
  return originalXHROpen.call(this, method, url, ...args);
};

// 重写fetch,同理跟踪请求生命周期
const originalFetch = window.fetch;
window.fetch = function(...args) {
  activeAjaxCount++;
  return originalFetch(...args)
    .finally(() => {
      activeAjaxCount--;
    });
};

// 封装等待所有AJAX完成的Promise函数
function waitForAllAjax() {
  return new Promise((resolve) => {
    const checkRequests = () => {
      if (activeAjaxCount === 0) {
        resolve();
      } else {
        setTimeout(checkRequests, 100); // 每100ms轮询一次
      }
    };
    checkRequests();
  });
}

// 使用示例:等待页面+所有AJAX完成后执行操作
async function runAfterFullLoad() {
  // 先等初始页面加载完成
  if (document.readyState !== "complete") {
    await new Promise(resolve => window.addEventListener('load', resolve));
  }
  // 再等所有AJAX请求结束
  await waitForAllAjax();
  // 这里写你的后续测试操作
  console.log('页面所有资源和AJAX请求都完成了!');
}

方法2:针对特定框架/库的专属方案

如果你的页面用了特定前端工具,可以直接利用它们的API简化操作:

  • jQuery:直接用$.active属性,它会返回当前活跃的AJAX请求数,判断$.active === 0即可
  • axios:创建全局请求拦截器,在请求发起时计数器+1,响应/错误时计数器-1,逻辑和方法1类似
  • Vue/React:如果是框架内的异步请求,可以在组件层面跟踪请求状态,或者用全局状态管理记录活跃请求数

方法3:利用浏览器Performance API

浏览器原生的Performance API可以捕获所有网络请求,你可以通过过滤条目来判断是否有未完成的AJAX请求:

function hasActiveAjaxRequests() {
  const resourceEntries = performance.getEntriesByType('resource');
  // 只筛选AJAX类型的请求,判断是否有未完成的(responseEnd为0表示还没结束)
  return resourceEntries.some(entry => 
    (entry.initiatorType === 'xmlhttprequest' || entry.initiatorType === 'fetch') 
    && entry.responseEnd === 0
  );
}

// 等待函数
function waitForAllAjax() {
  return new Promise((resolve) => {
    const check = () => {
      if (!hasActiveAjaxRequests()) {
        resolve();
      } else {
        setTimeout(check, 100);
      }
    };
    check();
  });
}

注意:这个方法会包含所有资源请求,所以需要通过initiatorType过滤出AJAX请求。


小提示:这些方法需要在页面加载早期注入(比如测试工具启动时、页面<head>阶段),才能捕获到所有AJAX请求,避免漏掉已经发起的异步操作。

内容的提问来源于stack exchange,提问作者moha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:11:30