Selenium 4 C# 通过Chrome DevTools拦截Fetch/XHR网络错误的方法
Selenium DevTools 拦截Fetch/XHR请求错误的正确实现
核心问题说明
requestId不匹配的本质原因是混用了不同DevTools域的ID体系、没有在同一条事件链路里传递ID。要捕获和浏览器Network面板预览完全一致的XHR/Fetch错误信息,不需要跨域调用接口,全程基于Network域的事件流处理即可。
第一步:修正初始化配置
原有代码只开启了Network域的基础开关,缺少响应内容捕获的必要配置,正确初始化代码如下(注意DevTools适配器版本要和本机Chrome大版本一致,以下以V120版本为例):
driver = new ChromeDriver(); driver.Manage().Window.Maximize(); IDevTools devTools = driver as IDevTools; DevToolsSession session = devTools.GetDevToolsSession(); var networkAdapter = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V120.Network.NetworkAdapter>(); // 启用Network域时配置缓冲区大小,否则拿不到响应体 await networkAdapter.Enable(new OpenQA.Selenium.DevTools.V120.Network.EnableCommandSettings { MaxTotalBufferSize = 100 * 1024 * 1024, MaxResourceBufferSize = 50 * 1024 * 1024 });
第二步:正确关联RequestId,避免匹配失败
全程只使用Network域事件参数中自带的RequestId,不要混用Fetch域、其他域返回的ID,通过本地字典维护请求全链路的映射关系:
- 订阅
RequestWillBeSent事件,过滤出XHR/Fetch类型请求,将事件返回的RequestId和请求基础信息存入本地字典 - 订阅
ResponseReceived事件,用事件参数自带的RequestId从字典取对应请求,判断响应状态是否为错误 - 错误请求直接用当前事件上下文里的
RequestId调用GetResponseBody接口,即可拿到和Network面板完全一致的响应内容 - 订阅
LoadingFailed事件,捕获网络层错误(跨域、超时、断网、CORS异常等),同样用事件自带的RequestId关联请求
完整事件订阅代码
// 自定义简单类存储请求基础信息 public class RequestInfo { public string Url { get; set; } public string Method { get; set; } public string PostData { get; set; } } // 本地字典维护请求ID映射 private readonly Dictionary<string, RequestInfo> _requestCache = new(); // 1. 记录所有XHR/Fetch请求 networkAdapter.RequestWillBeSent += (_, e) => { if (e.Type is OpenQA.Selenium.DevTools.V120.Network.ResourceType.XHR or OpenQA.Selenium.DevTools.V120.Network.ResourceType.Fetch) { _requestCache[e.RequestId] = new RequestInfo { Url = e.Request.Url, Method = e.Request.Method, PostData = e.Request.PostData }; } }; // 2. 捕获HTTP 4xx/5xx错误,拿到响应预览内容 networkAdapter.ResponseReceived += async (_, e) => { if (!_requestCache.TryGetValue(e.RequestId, out var request)) return; if (e.Response.Status >= 400 || e.Response.Status == 0) { var responseBody = await networkAdapter.GetResponseBody( new OpenQA.Selenium.DevTools.V120.Network.GetResponseBodyCommandSettings { RequestId = e.RequestId // 直接用当前事件的ID,100%匹配 }); // responseBody.Body 就是Network面板预览页展示的错误响应内容 // 在此处添加错误记录、断言等自定义逻辑 } }; // 3. 捕获网络层错误(无HTTP响应的场景) networkAdapter.LoadingFailed += (_, e) => { if (!_requestCache.TryGetValue(e.RequestId, out var request)) return; // e.ErrorText 对应Network面板展示的错误原因,比如net::ERR_CORS_ERROR、net::ERR_CONNECTION_TIMED_OUT var networkErrorMsg = e.ErrorText; // 在此处添加网络错误处理逻辑 };
常见踩坑说明
- 不要同时启用
Fetch.Enable做请求修改、又用Network域抓响应,两个域的RequestId是独立生成的,混拿必然匹配失败。如果只做错误捕获不需要修改请求,全程不要开启Fetch域 - DevTools适配器的大版本必须和本机安装的Chrome浏览器大版本一致,否则会出现字段缺失、ID格式异常的问题
- 调用
GetResponseBody的时机必须在ResponseReceived事件触发后、请求加载完成前,页面跳转、会话关闭后再调用会拿不到内容
浏览器Network面板XHR错误预览示例
内容的提问来源于stack exchange,提问作者Tamás Ladányi
相关产品推荐
相关产品推荐

