Chrome扩展监听XHR请求返回200但无法获取响应值该如何处理
Chrome扩展监听XHR请求获取响应内容解决方案
问题背景
你当前使用chrome.webRequest.onCompleted监听请求时,只能获取到请求元数据(状态码、请求地址等),无法拿到响应返回值,参考你提供的控制台截图:
你当前使用的监听代码如下:
chrome.webRequest.onCompleted.addListener(function (details) { console.log(details) }, {urls: ['<all_urls>']});
问题原因
chrome.webRequest API的设计定位是请求生命周期监控与拦截,本身不提供响应体的访问能力,因此你从details对象中无法获取到返回内容是预期表现。
可行解决方案
方案1:注入页面脚本重写XHR/Fetch接口(兼容性最好,无调试提示)
适用场景:需要静默监听指定站点的请求响应,Manifest V2/V3均支持。
- 第一步:配置
manifest.json的权限和资源声明(以Manifest V3为例)
{ "manifest_version": 3, "name": "请求响应监听", "version": "1.0", "content_scripts": [ { "matches": ["<all_urls>"], // 替换为实际需要监听的站点匹配规则 "js": ["content.js"], "run_at": "document_start" } ], "web_accessible_resources": [ { "resources": ["injected.js"], "matches": ["<all_urls>"] } ], "background": { "service_worker": "background.js" } }
- 第二步:编写
content.js,负责向页面注入重写逻辑,接收页面抛出的响应数据
// 向页面注入自定义脚本 const injectScript = document.createElement('script'); injectScript.src = chrome.runtime.getURL('injected.js'); document.documentElement.prepend(injectScript); // 监听页面脚本抛出来的响应事件 window.addEventListener('xhrResponseReceived', (e) => { // 可按需将响应数据传给后台服务工作线程 chrome.runtime.sendMessage({ type: 'responseCaptured', data: e.detail }); });
- 第三步:编写
injected.js,重写原生XHR和Fetch方法,捕获响应后抛出自定义事件
// 重写XHR接口 const originalOpen = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function(...args) { this.addEventListener('load', () => { window.dispatchEvent(new CustomEvent('xhrResponseReceived', { detail: { url: args[1], status: this.status, response: this.response, responseType: this.responseType } })); }); originalOpen.apply(this, args); }; // 重写Fetch接口(如果需要监听fetch类型请求) const originalFetch = window.fetch; window.fetch = async (...args) => { const response = await originalFetch(...args); const clonedResponse = response.clone(); // 可根据需求转换为json/blob等格式 const responseBody = await clonedResponse.text(); window.dispatchEvent(new CustomEvent('xhrResponseReceived', { detail: { url: args[0], status: response.status, response: responseBody } })); return response; };
方案2:使用chrome.debugger API获取响应体
适用场景:不需要隐藏调试状态,无需注入页面脚本,适配Manifest V2/V3。
注意:使用该API时浏览器顶部会弹出「当前正被软件调试」的提示条,对用户可见。
- 第一步:在
manifest.json中添加对应权限
{ "permissions": ["debugger", "tabs"], "host_permissions": ["<all_urls>"] }
- 第二步:编写
background.js监听请求获取响应
chrome.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => { if (changeInfo.status === 'complete' && tab.url) { // 附加调试器到目标标签页 await chrome.debugger.attach({tabId}, '1.3'); // 启用Network调试域 await chrome.debugger.sendCommand({tabId}, 'Network.enable'); // 监听响应接收完成事件 chrome.debugger.onEvent.addListener(async (debuggeeId, method, params) => { if (debuggeeId.tabId === tabId && method === 'Network.responseReceived') { // 跳过非200的响应 if (params.response.status !== 200) return; // 调用接口获取响应体 const responseBody = await chrome.debugger.sendCommand({tabId}, 'Network.getResponseBody', { requestId: params.requestId }); console.log('响应内容:', responseBody); } }); } });
内容的提问来源于stack exchange,提问作者ZFC AKADEMİ
相关产品推荐
相关产品推荐

