通过浏览器cdp协议中的实现
1. Network.responseReceived 事件
2. Network.loadingFinished 事件
3. Network.getResponseBody 方法
//.js
const aURL = '{监控的url}';//需要的监控网址URL
let debuggingTabId = null;//连接tabid
let networkEventListener = null;//监控函数
var shuju=null;//响应的数据
const requestMap = new Map();//筛选requestId
// ===================================================================
// 核心修改:监听 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("连接开始");
networkEventListener = (source, method, params) => {
// 确保事件来自我们正在调试的标签页
if (source.tabId !== debuggingTabId) return;
// --- 步骤 1: 在收到响应头时,记录请求信息 ---
if (method === 'Network.responseReceived') {
const { requestId, response } = params;
// 检查 URL 是否是我们关心的
if (response.url.includes(aURL)) {
console.log(`[记录] 找到目标请求,Request ID: ${requestId}, URL:${response.url}`);
// 将 requestId 和 URL 存入 Map
requestMap.set(requestId, response.url);
}
}
// --- 步骤 2: 在请求完全加载后,获取响应体 ---
if (method === 'Network.loadingFinished') {
const { requestId } = params;
// 从 Map 中查找这个 requestId 是否是我们关心的
const targetUrl = requestMap.get(requestId);
if (targetUrl) {
console.log(`[处理] 目标请求加载完成,Request ID: ${requestId}`);
// 步骤 3: 调用 getResponseBody 获取响应体
chrome.debugger.sendCommand(
source,
'Network.getResponseBody',
{ requestId: requestId },
(result) => {
// 步骤 4: 处理响应体
if (chrome.runtime.lastError) {
console.error("获取响应体失败:", chrome.runtime.lastError.message);
chrome.runtime.sendMessage({ action: 'error', error: `Failed to get body: ${chrome.runtime.lastError.message}` });
// 即使失败也要清理 Map
requestMap.delete(requestId);
return;
}
console.log("成功获取响应数据!");
let bodyContent = result.body;
if (result.base64Encoded) {
// 如果是二进制内容(如图片),通常需要解码或特殊处理
// 这里只做简单提示
bodyContent = `二进制内容 (Base64): ${result.body.substring(0, 100)}...`;
console.warn("响应体是 Base64 编码的二进制数据。");
}
// 在这里处理你的数据
try {
shuju = JSON.parse(bodyContent);
console.log("处理后的数据:", shuju);
} catch (e) {
console.error("解析 JSON 失败:", e);
console.log("原始响应体:11", bodyContent);
}
// 【重要】处理完成后,从 Map 中移除该请求,防止内存泄漏
requestMap.delete(requestId);
}
);
}
}
};
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();
}
}
大佬这个咋用呢,浏览器控制选 运行后台脚本(MV2版扩展) 吗
已现浏览器插件的模式,不太好将其封装成子程序调用,如果你对浏览器插件开发和请求响应有研究或有这方面的知识储备,我可以提供思路,你可以自己尝试封装调用
就是不会这个,看来只能放弃了.0.0.
这个差不多构建好了,如果需要使用的话,留一个联系方式,我给你说一下,暂不公布
好的,大佬我加你了