自动化测试中如何用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
相关产品推荐
相关产品推荐

