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

Firefox个人扩展拦截GET请求无法获取目标响应数据求助

解决Firefox扩展获取GET请求响应体的问题

你当前使用webRequest.onCompleted只能获取请求的元数据(如URL、状态码),无法直接拿到响应体内容,这就是为什么你看到responseSize: 0却在开发者工具里能看到响应的原因——这个API设计上就不提供响应内容。

要获取目标JSON响应,有两种可靠的方法:

方法1:使用webRequest.filterResponseData拦截响应流

这个API允许你拦截并读取HTTP响应的内容,是Firefox扩展获取响应体的标准方式。

步骤1:更新manifest权限

确保你的manifest.json包含以下权限:

{
  "manifest_version": 3,
  "permissions": ["webRequest", "webRequestBlocking", "https://www.tumblr.com/*"],
  "background": {
    "scripts": ["background.js"]
  }
}

步骤2:后台脚本实现拦截

替换你现有的代码为:

browser.runtime.onInstalled.addListener(() => {
  // 监听请求完成前的阶段,用于创建响应过滤器
  browser.webRequest.onHeadersReceived.addListener(
    (details) => {
      // 只处理目标API请求
      if (details.url.includes("/api/v2/user/counts")) {
        // 创建响应过滤器
        const filter = browser.webRequest.filterResponseData(details.requestId);
        const decoder = new TextDecoder("utf-8");
        let responseBody = "";

        // 监听响应数据块
        filter.ondata = (event) => {
          responseBody += decoder.decode(event.data, { stream: true });
          // 把数据传回原流,不影响页面接收
          filter.write(event.data);
        };

        // 响应结束时解析JSON
        filter.onstop = () => {
          filter.disconnect();
          try {
            const data = JSON.parse(responseBody);
            console.log("获取到目标响应:", data);
            // 这里可以处理你需要的字段:data.blog_notification_counts、data.unread等
          } catch (e) {
            console.error("解析响应失败:", e);
          }
        };

        // 处理错误
        filter.onerror = (error) => {
          console.error("过滤器错误:", error);
          filter.disconnect();
        };
      }
    },
    { urls: ["https://www.tumblr.com/*"] },
    ["blocking"] // 必须加blocking才能创建过滤器
  );
});

方法2:重新发起请求获取响应

如果拦截流的方式对你来说太复杂,也可以在onCompleted回调中拿到请求URL后,用后台脚本的fetch重新请求(后台脚本不受CORS限制):

后台脚本代码

browser.runtime.onInstalled.addListener(() => {
  browser.webRequest.onCompleted.addListener(
    async (details) => {
      if (details.url.includes("/api/v2/user/counts") && details.statusCode === 200) {
        try {
          const response = await fetch(details.url, {
            credentials: "include" // 带上当前用户的cookie,确保请求有权限
          });
          const data = await response.json();
          console.log("获取到目标响应:", data);
          // 处理需要的字段
        } catch (e) {
          console.error("重新请求失败:", e);
        }
      }
    },
    { urls: ["https://www.tumblr.com/*"] }
  );
});

注意:这种方法会发起二次请求,可能浪费资源,建议优先使用方法1。

关键注意事项

  • 确保manifest的权限配置正确,缺少权限会导致API调用失败;
  • 针对HTTP/2请求,responseSize字段可能不会准确统计,但不影响filterResponseData读取内容;
  • 如果目标请求需要特定的请求头(如Authorization),方法2的fetch需要手动添加对应头信息(可以从details.requestHeaders中获取)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 01:17:45