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

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İ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 07:06:03