ljjh#True
// background.js
// 使用 Map 存储拦截的请求数据,键为 interceptionId
const interceptedRequests = new Map();
// 使用 Map 存储 requestId 到 interceptionId 的映射
const requestIdToInterceptionIdMap = new Map();
// 存储已附加调试器的标签页ID
const debuggedTabs = new Set();
/**
* 生成唯一的 uniqueRequestId
*/
function generateRequestId() {
return `req_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;
}
/**
* 监听浏览器标签页更新,自动附加调试器
*/
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (changeInfo.status === 'complete' && !debuggedTabs.has(tabId)) {
// 仅附加到 http 和 https 协议的标签页
if (/^https?:\/\//.test(tab.url)) {
attachDebugger(tabId);
}
}
});
/**
* 监听新标签页创建,自动附加调试器
*/
chrome.tabs.onCreated.addListener((tab) => {
if (/^https?:\/\//.test(tab.url)) {
attachDebugger(tab.id);
}
});
/**
* 附加调试器到指定标签页
*/
function attachDebugger(tabId) {
try {
chrome.debugger.attach({ tabId: tabId }, '1.3', () => {
if (chrome.runtime.lastError) {
console.error(`Debugger attach failed: ${chrome.runtime.lastError.message}`);
return;
}
debuggedTabs.add(tabId);
console.log(`Debugger attached to tab ${tabId}`);
// 启用网络域
chrome.debugger.sendCommand({ tabId: tabId }, 'Network.enable');
// 设置请求捕获的过滤器,拦截 URL 包含 '/build' 的所有类型请求
chrome.debugger.sendCommand({ tabId: tabId }, 'Network.setRequestInterception', {
patterns: [
{ urlPattern: '*://*/*/build*', interceptionStage: 'Request' }
]
}, (response) => {
if (chrome.runtime.lastError) {
console.error(`Failed to set request interception: ${chrome.runtime.lastError.message}`);
} else {
console.log(`Request interception set for tab ${tabId}`);
}
});
});
} catch (error) {
console.error(`Failed to attach debugger to tab ${tabId}:`, error);
}
}
/**
* 监听调试器的网络事件
*/
chrome.debugger.onEvent.addListener((source, method, params) => {
if (method === 'Network.requestIntercepted') {
handleRequestIntercepted(source.tabId, params);
}
if (method === 'Network.responseReceived') {
handleResponseReceived(source.tabId, params);
}
// 监听加载完成事件
if (method === 'Network.loadingFinished') {
handleLoadingFinished(source.tabId, params);
}
});
/**
* 处理 Network.requestIntercepted 事件
*/
function handleRequestIntercepted(tabId, params) {
const { interceptionId, requestId, request, resourceType } = params;
const { url, method, headers, postData } = request;
// 检查是否成功获取到 url
if (!url) {
console.warn(`[background.js] 拦截ID ${interceptionId} 的请求缺少 URL 信息`);
// 继续拦截的请求,避免阻塞
chrome.debugger.sendCommand({ tabId: tabId }, 'Network.continueInterceptedRequest', { interceptionId }, (response) => {
if (chrome.runtime.lastError) {
console.error(`Failed to continue request ${interceptionId}: ${chrome.runtime.lastError.message}`);
} else {
console.log(`Continued request ${interceptionId}`);
}
});
return;
}
// 仅处理 URL 包含 '/build' 的请求
if (!url.includes('/build')) {
// 继续拦截的请求,避免阻塞
chrome.debugger.sendCommand({ tabId: tabId }, 'Network.continueInterceptedRequest', { interceptionId }, (response) => {
if (chrome.runtime.lastError) {
console.error(`Failed to continue request ${interceptionId}: ${chrome.runtime.lastError.message}`);
} else {
console.log(`Continued request ${interceptionId}`);
}
});
return;
}
console.log(`存储请求信息 ${JSON.stringify({
url: url,
method: method,
headers: headers,
payload: postData || null,
type: resourceType,
responseContent: null
})}`)
// 存储请求信息
interceptedRequests.set(interceptionId, {
url: url,
method: method,
headers: headers,
payload: postData || null,
type: resourceType,
responseContent: null
});
// 存储 requestId 到 interceptionId 的映射
requestIdToInterceptionIdMap.set(requestId, interceptionId);
console.log(`[background.js] 捕获到请求 - 拦截ID: ${interceptionId}, 类型: ${resourceType}, 方法: ${method}, URL: ${url}`);
// 继续拦截的请求,确保请求不会被阻塞
chrome.debugger.sendCommand({ tabId: tabId }, 'Network.continueInterceptedRequest', { interceptionId }, (response) => {
if (chrome.runtime.lastError) {
console.error(`Failed to continue request ${interceptionId}: ${chrome.runtime.lastError.message}`);
} else {
console.log(`Continued request ${interceptionId}`);
}
});
}
/**
* 处理 Network.responseReceived 事件
*/
function handleResponseReceived(tabId, params) {
const { requestId, response, type } = params;
// 检查是否有对应的 interceptionId
if (!requestIdToInterceptionIdMap.has(requestId)) {
return;
}
const interceptionId = requestIdToInterceptionIdMap.get(requestId);
const requestInfo = interceptedRequests.get(interceptionId);
if (!requestInfo) {
return;
}
// 更新请求类型(有时 response.type 可能更准确)
requestInfo.type = type;
console.log(`[background.js] 捕获到响应 - 类型: ${type}, URL: ${response.url}`);
}
/**
* 处理 Network.loadingFinished 事件
*/
function handleLoadingFinished(tabId, params) {
const { requestId } = params;
// 检查是否有对应的 interceptionId
if (!requestIdToInterceptionIdMap.has(requestId)) {
return;
}
const interceptionId = requestIdToInterceptionIdMap.get(requestId);
requestIdToInterceptionIdMap.delete(requestId);
const requestInfo = interceptedRequests.get(interceptionId);
if (!requestInfo) {
return;
}
// 发送命令获取响应内容
chrome.debugger.sendCommand({ tabId: tabId }, 'Network.getResponseBody', { requestId }, (bodyResponse) => {
if (chrome.runtime.lastError) {
console.error(`Failed to get response body for requestId ${requestId}: ${chrome.runtime.lastError.message}`);
interceptedRequests.delete(interceptionId);
return;
}
const { body, base64Encoded } = bodyResponse;
const responseContent = base64Encoded ? atob(body) : body;
console.log(`[background.js] 捕获到响应内容 - 方法: ${requestInfo.method}, URL: ${requestInfo.url}, 内容长度: ${responseContent.length}`);
// 生成唯一的 uniqueRequestId
const uniqueRequestId = generateRequestId();
// 存储完整的请求和响应信息
console.log(`存储完整的请求和响应信息: ${JSON.stringify({
requestId: uniqueRequestId,
url: requestInfo.url,
method: requestInfo.method,
payload: requestInfo.payload,
headers: requestInfo.headers,
responseContent: responseContent,
type: requestInfo.type
})}`);
interceptedRequests.set(uniqueRequestId, {
requestId: uniqueRequestId,
url: requestInfo.url,
method: requestInfo.method,
payload: requestInfo.payload,
headers: requestInfo.headers,
responseContent: responseContent,
type: requestInfo.type
});
console.log(`[background.js] 请求已存储,uniqueRequestId: ${uniqueRequestId}`);
// 移除原始的 interceptionId
interceptedRequests.delete(interceptionId);
});
}
/**
* 监听来自弹出页面的消息
*/
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.action === "getDocumentRequests") {
// 将 Map 转换为数组进行传输
const data = Array.from(interceptedRequests.values());
sendResponse({ data: data });
} else if (request.action === "clearDocumentRequests") {
interceptedRequests.clear();
requestIdToInterceptionIdMap.clear();
sendResponse({ data: "清除成功" });
console.log("interceptedRequests 和 requestIdToInterceptionIdMap 已清除");
}
});
/**
* 在扩展卸载时,移除所有附加的调试器
*/
chrome.runtime.onSuspend.addListener(() => {
debuggedTabs.forEach(tabId => {
chrome.debugger.detach({ tabId: tabId }, () => {
console.log(`Debugger detached from tab ${tabId}`);
});
});
});