通过浏览器插件cdp协议获取网页api部分网址响应数据原理(mv3版)

动作开发 · 1702 次浏览
涛涛涛 创建于 2天21小时前
通过浏览器cdp协议中的实现
1. Network.responseReceived 事件
2. Network.getResponseBody 方法

//需要获取响应数据api网址,可以是一部分,网址包含就行
const substr = '*****';
 
// 附加调试器并开始监听
function attachDebugger(tabId) {
  chrome.debugger.attach({ tabId }, '1.3', () => {
    if (chrome.runtime.lastError) {
      console.error("Failed to attach debugger:", chrome.runtime.lastError.message);
      return;
    }
    console.log(`Debugger attached to tab ${tabId}`);
 
    // 启用 Network 域
    chrome.debugger.sendCommand({ tabId }, 'Network.enable', {}, () => {
      if (chrome.runtime.lastError) {
        console.error("Failed to enable Network domain:", chrome.runtime.lastError.message);
        return;
      }
      console.log("Network domain enabled.");
    });
  });
}
 
// 分离调试器
function detachDebugger(tabId) {
  chrome.debugger.detach({ tabId }, () => {
    if (chrome.runtime.lastError) {
      // 忽略分离时的错误,比如标签页已关闭
      console.log("Info:", chrome.runtime.lastError.message);
      return;
    }
    console.log(`Debugger detached from tab ${tabId}`);
  });
}
 
// 监听 CDP 事件
chrome.debugger.onEvent.addListener((source, method, params) => {
  if (method === 'Network.responseReceived') {
    const { requestId, response } = params;
 
    // 只获取目标 API 的响应
    if (response.url.includes(substr)) {
      console.log(`111: ${requestId}`);
 
      // 使用 requestId 获取响应体
      chrome.debugger.sendCommand(
        source,
        'Network.getResponseBody',
        { requestId: requestId },
        (result) => {
          if (chrome.runtime.lastError) {
            console.error("Failed to get response body:", chrome.runtime.lastError.message);
            return;
          }
          //响应数据body为字符串
          let bodyContent = result.body;
          console.log("222:", bodyContent);
          
        }
      );
    }
  }
});

侧耳倾听& 2天18小时前 :

大佬这个咋用呢,浏览器控制选  运行后台脚本(MV2版扩展) 吗

侧耳倾听& 最后更新于 2天18小时前
涛涛涛 回复 侧耳倾听& 2天5小时前 :

已现浏览器插件的模式,不太好将其封装成子程序调用,如果你对浏览器插件开发和请求响应有研究或有这方面的知识储备,我可以提供思路,你可以自己尝试封装调用

侧耳倾听& 回复 涛涛涛 2天0小时前 :

就是不会这个,看来只能放弃了.0.0.

涛涛涛 回复 侧耳倾听& 1天23小时前 :


涛涛涛 最后更新于 1天20小时前
回复内容
涛涛涛 1天20小时前
#1

完善一些逻辑连接方式和断开方式

//.js 
const aURL = '监控的url';//需要的监控网址URL
let debuggingTabId = null;//连接tabid
let networkEventListener = null;//监控函数
var shuju=null;//响应的数据

// ===================================================================
// 核心修改:监听 detach 事件,这是处理“手动断开”的关键
// ===================================================================
chrome.debugger.onDetach.addListener((source, reason) => {
  console.log(`断开: ${reason}.`);
  
  // 检查这个分离事件是否来自我们正在调试的标签页
  if (source.tabId === debuggingTabId) {
    // 执行清理操作
    performCleanup();
  }
});

// ===================================================================
// 将清理逻辑封装到独立函数中
// ===================================================================
function performCleanup() {
  if (networkEventListener) {
    chrome.debugger.onEvent.removeListener(networkEventListener);
    networkEventListener = null;
    console.log("清除监控.");
  }
  
  // 重置状态
  debuggingTabId = null;
}


function startDebugging(tabId) {
  if (debuggingTabId) {
    console.log("Already debugging another tab.");
    return;
  }
  debuggingTabId = tabId;

  // 步骤 1: 附加调试器
  chrome.debugger.attach({ tabId }, '1.3', () => {
    if (chrome.runtime.lastError) {
      console.error("Step 1 Failed: Attach debugger", chrome.runtime.lastError.message);
      chrome.runtime.sendMessage({ action: 'error', error: `Failed to attach: ${chrome.runtime.lastError.message}` });
      // 如果附加失败,也要清理状态
      performCleanup();
      return;
    }
    console.log("连接开始");

    // 步骤 2: 监听事件
    networkEventListener = (source, method, params) => {
      if (source.tabId !== debuggingTabId) return;

      if (method === 'Network.responseReceived') {
        const { requestId, response } = params;
        if (response.url.includes(aURL)) {
          console.log(`响应的Request ID: ${requestId}`);

          // 步骤 5: 调用 getResponseBody
          chrome.debugger.sendCommand(
            source,
            'Network.getResponseBody',
            { requestId: requestId },
            (result) => {
              // 步骤 6: 处理响应体
              if (chrome.runtime.lastError) {
                console.error("Step 6 Failed: Get response body", chrome.runtime.lastError.message);
                chrome.runtime.sendMessage({ action: 'error', error: `Failed to get body: ${chrome.runtime.lastError.message}` });
                return;
              }
              console.log("响应数据");
              
              let bodyContent = result.body;
              if (result.base64Encoded) {
                bodyContent = `Binary content (Base64): ${result.body.substring(0, 100)}...`;
              }
              shuju=bodyContent;
            }
          );
        }
      }
    };
    chrome.debugger.onEvent.addListener(networkEventListener);


    // 步骤 3: 启用 Network 域
    chrome.debugger.sendCommand({ tabId }, 'Network.enable', {}, () => {
      if (chrome.runtime.lastError) {
        console.error("Step 3 Failed: Enable Network domain", chrome.runtime.lastError.message);
        // 如果启用失败,主动断开,onDetach 会处理清理
        chrome.debugger.detach({ tabId });
        return;
      }
      console.log("3333");
    });
  });
}

function detachDebugger() {
    if (debuggingTabId) {
      console.log("主动断开");
      chrome.debugger.detach({ tabId: debuggingTabId });
      performCleanup();
    }
}

涛涛涛 最后更新于 1天17小时前
回复主贴