Files
chromeEvent/content-script.js
2026-01-29 12:03:28 +08:00

874 lines
42 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Content Script - 使用 DevTools Network API 获取 XHR 请求
*
* 注意:这个脚本只在 DevTools 面板中使用
* 实际的请求捕获通过 chrome.devtools.network.onRequestFinished 实现
*/
// 这个文件现在已经不需要了,因为请求捕获在 DevTools 面板中完成
// 但保留文件以避免错误
// 将完整的拦截脚本注入到页面上下文
const script = document.createElement('script');
script.textContent = `
(function() {
'use strict';
console.log('🔧 [页面上下文] 拦截脚本已执行');
console.log('🔧 [页面上下文] XMLHttpRequest 类型:', typeof XMLHttpRequest);
console.log('🔧 [页面上下文] fetch 类型:', typeof fetch);
// 在页面上下文中存储解密记录
if (!window.__XHR_DECRYPT_DATA__) {
window.__XHR_DECRYPT_DATA__ = {
requests: [],
addRequest: function(record) {
this.requests.push(record);
if (this.requests.length > 100) {
this.requests.shift();
}
// 通知 content script
window.dispatchEvent(new CustomEvent('__XHR_DECRYPTED__', { detail: record }));
},
getRequests: function() {
return this.requests;
},
clear: function() {
this.requests = [];
}
};
}
const decryptedData = window.__XHR_DECRYPT_DATA__;
const requestHeadersMap = new Map();
const skipDecryptPaths = ['v1/picture/upload'];
// ========== 密钥获取策略管理器 ==========
const KeyGetStrategies = {
strategies: [],
// 注册密钥获取策略
register: function(strategy) {
if (strategy && typeof strategy.getName === 'function' && typeof strategy.getKey === 'function') {
this.strategies.push({
name: strategy.getName(),
priority: strategy.priority || 100,
getKey: strategy.getKey,
canHandle: strategy.canHandle || (() => true)
});
// 按优先级排序(数字越小优先级越高)
this.strategies.sort((a, b) => a.priority - b.priority);
}
},
// 获取密钥(按优先级尝试所有策略)
getKey: function(url, uuid, requestHeaders) {
for (const strategy of this.strategies) {
try {
if (strategy.canHandle(url, uuid, requestHeaders)) {
const key = strategy.getKey(url, uuid, requestHeaders);
if (key) {
console.log('🔑 [密钥策略] 使用策略:', strategy.name, '获取密钥成功');
return { key: key, strategy: strategy.name };
}
}
} catch (error) {
console.warn('🔑 [密钥策略] 策略', strategy.name, '执行失败:', error);
continue;
}
}
console.warn('🔑 [密钥策略] 所有策略都无法获取密钥');
return null;
},
// 初始化默认策略
init: function() {
// 策略1: 从页面工具获取密钥(优先级最高)
this.register({
name: '页面工具获取',
priority: 10,
canHandle: function(url, uuid, requestHeaders) {
return window.__DECRYPT_TOOLS__ && window.__DECRYPT_TOOLS__.getKey;
},
getKey: function(url, uuid, requestHeaders) {
const tools = window.__DECRYPT_TOOLS__;
if (tools && tools.getKey) {
return tools.getKey(url, uuid);
}
return null;
}
});
// 策略2: 从请求头计算密钥timestamp + TraceId
this.register({
name: '请求头计算',
priority: 20,
canHandle: function(url, uuid, requestHeaders) {
const timestamp = requestHeaders?.time || requestHeaders?.Time || '';
const traceId = requestHeaders?.TraceId || requestHeaders?.['trace-id'] || '';
return !!(timestamp && traceId);
},
getKey: function(url, uuid, requestHeaders) {
const timestamp = requestHeaders?.time || requestHeaders?.Time || '';
const traceId = requestHeaders?.TraceId || requestHeaders?.['trace-id'] || '';
if (timestamp && traceId) {
return String(timestamp + traceId).slice(0, 16);
}
return null;
}
});
// 可以在这里添加更多密钥获取策略
// 例如:从 localStorage 获取、从 URL 参数获取、从 Cookie 获取等
}
};
// ========== 解密策略管理器 ==========
const DecryptStrategies = {
strategies: [],
// 注册解密策略
register: function(strategy) {
if (strategy && typeof strategy.getName === 'function' && typeof strategy.decrypt === 'function') {
this.strategies.push({
name: strategy.getName(),
priority: strategy.priority || 100,
decrypt: strategy.decrypt,
canHandle: strategy.canHandle || (() => true)
});
// 按优先级排序
this.strategies.sort((a, b) => a.priority - b.priority);
}
},
// 解密数据(按优先级尝试所有策略)
decrypt: function(encryptedData, key, isRequest = false) {
for (const strategy of this.strategies) {
try {
if (strategy.canHandle(encryptedData, key, isRequest)) {
const decrypted = strategy.decrypt(encryptedData, key, isRequest);
if (decrypted !== null && decrypted !== undefined && decrypted !== encryptedData) {
console.log('🔓 [解密策略] 使用策略:', strategy.name, '解密成功');
return { data: decrypted, strategy: strategy.name };
}
}
} catch (error) {
console.warn('🔓 [解密策略] 策略', strategy.name, '执行失败:', error);
continue;
}
}
console.warn('🔓 [解密策略] 所有策略都无法解密数据');
return { data: encryptedData, strategy: null };
},
// 初始化默认策略
init: function() {
// 策略1: 使用页面工具解密(优先级最高)
this.register({
name: '页面工具解密',
priority: 10,
canHandle: function(encryptedData, key, isRequest) {
return window.__DECRYPT_TOOLS__ && window.__DECRYPT_TOOLS__.Decrypt;
},
decrypt: function(encryptedData, key, isRequest) {
const tools = window.__DECRYPT_TOOLS__;
if (!tools || !tools.Decrypt) {
return null;
}
try {
if (isRequest) {
// 请求数据格式:{ data: "base64String" }
if (encryptedData && encryptedData.data && typeof encryptedData.data === 'string') {
const decrypted = tools.Decrypt(encryptedData.data, key);
if (decrypted) {
return JSON.parse(decrypted);
}
}
} else {
// 响应数据格式:字符串或对象
if (typeof encryptedData === 'string') {
const decrypted = tools.Decrypt(encryptedData, key);
if (decrypted) {
try {
return JSON.parse(decrypted);
} catch (e) {
if (window.JSON5) {
return window.JSON5.parse(decrypted);
}
return decrypted;
}
}
}
}
} catch (error) {
console.error('解密失败:', error);
}
return null;
}
});
// 策略2: 使用 CryptoJS 直接解密(如果可用)
this.register({
name: 'CryptoJS 解密',
priority: 20,
canHandle: function(encryptedData, key, isRequest) {
return typeof CryptoJS !== 'undefined' && key;
},
decrypt: function(encryptedData, key, isRequest) {
try {
if (typeof CryptoJS === 'undefined') {
return null;
}
let dataToDecrypt = null;
if (isRequest) {
if (encryptedData && encryptedData.data && typeof encryptedData.data === 'string') {
dataToDecrypt = encryptedData.data;
} else {
return null;
}
} else {
if (typeof encryptedData === 'string') {
dataToDecrypt = encryptedData;
} else {
return null;
}
}
if (!dataToDecrypt) {
return null;
}
// 清理数据
const cleanData = dataToDecrypt.replace(/\s/g, '').replace(/"/g, '');
const cleanKey = key.replace(/\s/g, '').replace(/"/g, '');
// AES 解密
const decrypt = CryptoJS.AES.decrypt(
cleanData,
CryptoJS.enc.Utf8.parse(cleanKey),
{
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
}
);
const decrypted = decrypt.toString(CryptoJS.enc.Utf8);
if (!decrypted) {
return null;
}
// 尝试解析 JSON
try {
return JSON.parse(decrypted);
} catch (e) {
if (window.JSON5) {
return window.JSON5.parse(decrypted);
}
return decrypted;
}
} catch (error) {
return null;
}
}
});
// 可以在这里添加更多解密策略
// 例如:其他加密算法、不同的填充方式等
}
};
// 初始化策略管理器
KeyGetStrategies.init();
DecryptStrategies.init();
// ========== 便捷函数 ==========
// 获取密钥
function getTimestampKey(url, uuid, requestHeaders) {
const result = KeyGetStrategies.getKey(url, uuid, requestHeaders);
return result ? result.key : null;
}
// 解密请求数据
function decryptRequestData(encryptedData, timestampKey) {
if (!timestampKey) {
return encryptedData;
}
const result = DecryptStrategies.decrypt(encryptedData, timestampKey, true);
return result.data;
}
// 解密响应数据
function decryptResponseData(encryptedData, timestampKey) {
if (!timestampKey) {
return encryptedData;
}
const result = DecryptStrategies.decrypt(encryptedData, timestampKey, false);
return result.data;
}
// 暴露策略管理器,允许外部注册新策略
window.__XHR_DECRYPT_STRATEGIES__ = {
keyGetStrategies: KeyGetStrategies,
decryptStrategies: DecryptStrategies
};
// ========== 拦截 XMLHttpRequest ==========
// 必须在页面脚本运行前拦截,否则会被覆盖
(function() {
if (typeof XMLHttpRequest === 'undefined') {
console.warn('⚠️ [页面上下文] XMLHttpRequest 未定义');
return;
}
// 保存原始函数(必须在任何其他脚本运行前保存)
const originalXHR = window.XMLHttpRequest;
const originalOpen = XMLHttpRequest.prototype.open;
const originalSend = XMLHttpRequest.prototype.send;
const originalSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
// 检查是否已经被拦截过
const openStr = originalOpen.toString();
if (openStr.includes('_method') || openStr.includes('__XHR_DECRYPT')) {
console.log('⚠️ [页面上下文] XHR 可能已被其他脚本拦截');
}
XMLHttpRequest.prototype.open = function(method, url, ...args) {
this._method = method;
this._url = url;
this._requestHeaders = {};
requestHeadersMap.set(this, {});
console.log('🔍 [页面上下文] 拦截 XHR open:', method, url);
// 确保返回正确的结果
const result = originalOpen.apply(this, [method, url, ...args]);
return result;
};
XMLHttpRequest.prototype.setRequestHeader = function(name, value) {
if (!this._requestHeaders) {
this._requestHeaders = {};
}
this._requestHeaders[name] = value;
const headers = requestHeadersMap.get(this) || {};
headers[name] = value;
requestHeadersMap.set(this, headers);
return originalSetRequestHeader.apply(this, [name, value]);
};
XMLHttpRequest.prototype.send = function(body) {
const url = this._url;
const method = this._method;
const requestId = Date.now() + Math.random();
const shouldSkip = skipDecryptPaths.some(path => url.includes(path));
// 监听响应
this.addEventListener('loadend', function() {
if (shouldSkip) return;
try {
const headers = requestHeadersMap.get(this) || {};
const uuid = this.getResponseHeader('uuid');
if (!uuid) {
return;
}
// 获取密钥(包含策略信息)
const keyResult = KeyGetStrategies.getKey(url, uuid, headers);
if (!keyResult || !keyResult.key) {
console.warn('无法获取密钥', { url, uuid, headers });
return;
}
const timestampKey = keyResult.key;
const keyStrategy = keyResult.strategy;
// 解密请求数据(包含策略信息)
let requestBody = null;
let requestDecryptStrategy = null;
if (body) {
try {
const parsed = typeof body === 'string' ? JSON.parse(body) : body;
const decryptResult = DecryptStrategies.decrypt(parsed, timestampKey, true);
requestBody = decryptResult.data;
requestDecryptStrategy = decryptResult.strategy;
} catch (e) {
requestBody = body;
}
}
// 解密响应数据(包含策略信息)
let responseData = null;
try {
if (this.responseText) {
responseData = JSON.parse(this.responseText);
}
} catch (e) {
responseData = this.responseText || this.response;
}
const decryptResult = DecryptStrategies.decrypt(responseData, timestampKey, false);
const decryptedResponse = decryptResult.data;
const responseDecryptStrategy = decryptResult.strategy;
// 记录解密结果
const decryptedRecord = {
id: requestId,
url: url,
method: method,
uuid: uuid,
timestampKey: timestampKey,
keyStrategy: keyStrategy,
request: requestBody,
requestDecryptStrategy: requestDecryptStrategy,
response: decryptedResponse,
responseDecryptStrategy: responseDecryptStrategy,
timestamp: new Date().toISOString()
};
// 存储到页面上下文
decryptedData.addRequest(decryptedRecord);
// 输出到控制台
console.group('🔓 XHR 解密 [' + method + '] ' + url);
console.log('🔑 密钥:', timestampKey, '(策略: ' + keyStrategy + ')');
if (requestDecryptStrategy) {
console.log('📤 请求:', requestBody, '(解密策略: ' + requestDecryptStrategy + ')');
} else {
console.log('📤 请求:', requestBody);
}
if (responseDecryptStrategy) {
console.log('📥 响应:', decryptedResponse, '(解密策略: ' + responseDecryptStrategy + ')');
} else {
console.log('📥 响应:', decryptedResponse);
}
console.log('📍 UUID:', uuid);
console.groupEnd();
} catch (error) {
console.error('❌ 解密过程出错:', error);
}
});
return originalSend.apply(this, [body]);
};
console.log('✅ [页面上下文] XHR 拦截已设置');
console.log('✅ [页面上下文] originalOpen 类型:', typeof originalOpen);
console.log('✅ [页面上下文] XMLHttpRequest.prototype.open:', typeof XMLHttpRequest.prototype.open);
// 验证拦截是否真的生效
setTimeout(function() {
const testXhr = new XMLHttpRequest();
const testOpenStr = testXhr.open.toString();
if (testOpenStr.includes('_method')) {
console.log('✅ [页面上下文] XHR 拦截验证成功');
} else {
console.error('❌ [页面上下文] XHR 拦截验证失败,可能被覆盖');
console.error(' 当前 open 函数:', testOpenStr.substring(0, 100));
}
}, 500);
})();
// ========== 拦截 Fetch ==========
// 必须在页面脚本运行前拦截
(function() {
if (typeof fetch === 'undefined' || !window.fetch) {
console.warn('⚠️ [页面上下文] fetch 未定义');
return;
}
// 保存原始函数
const originalFetch = window.fetch;
// 检查是否已经被拦截过
const fetchStr = originalFetch.toString();
if (fetchStr.includes('clonedResponse') || fetchStr.includes('__XHR_DECRYPT')) {
console.log('⚠️ [页面上下文] Fetch 可能已被其他脚本拦截');
}
window.fetch = function(...args) {
const [url, options = {}] = args;
const method = options.method || 'GET';
const requestId = Date.now() + Math.random();
const shouldSkip = skipDecryptPaths.some(path => url.includes(path));
const originalBody = options.body;
console.log('🔍 [页面上下文] 拦截 Fetch:', method, url);
return originalFetch.apply(this, args).then(async (response) => {
if (shouldSkip) return response;
try {
const clonedResponse = response.clone();
const uuid = clonedResponse.headers.get('uuid');
if (!uuid) {
return response;
}
const headers = options.headers || {};
const timestamp = headers.time || headers.Time || '';
const traceId = headers.TraceId || headers['trace-id'] || '';
// 获取密钥(包含策略信息)
const keyResult = KeyGetStrategies.getKey(url, uuid, { time: timestamp, TraceId: traceId });
if (!keyResult || !keyResult.key) {
console.warn('无法获取密钥 (Fetch)', { url, uuid });
return response;
}
const timestampKey = keyResult.key;
const keyStrategy = keyResult.strategy;
// 解密请求数据(包含策略信息)
let requestBody = null;
let requestDecryptStrategy = null;
if (originalBody) {
try {
if (typeof originalBody === 'string') {
const parsed = JSON.parse(originalBody);
const decryptResult = DecryptStrategies.decrypt(parsed, timestampKey, true);
requestBody = decryptResult.data;
requestDecryptStrategy = decryptResult.strategy;
} else {
requestBody = originalBody;
}
} catch (e) {
requestBody = originalBody;
}
}
// 解密响应数据(包含策略信息)
let responseData = null;
try {
const text = await clonedResponse.text();
if (text) {
try {
responseData = JSON.parse(text);
} catch (e) {
responseData = text;
}
}
} catch (e) {
console.error('读取响应数据失败:', e);
}
const decryptResult = DecryptStrategies.decrypt(responseData, timestampKey, false);
const decryptedResponse = decryptResult.data;
const responseDecryptStrategy = decryptResult.strategy;
// 记录解密结果
const decryptedRecord = {
id: requestId,
url: url,
method: method,
uuid: uuid,
timestampKey: timestampKey,
keyStrategy: keyStrategy,
request: requestBody,
requestDecryptStrategy: requestDecryptStrategy,
response: decryptedResponse,
responseDecryptStrategy: responseDecryptStrategy,
timestamp: new Date().toISOString()
};
// 存储到页面上下文
decryptedData.addRequest(decryptedRecord);
// 输出到控制台
console.group('🔓 Fetch 解密 [' + method + '] ' + url);
console.log('🔑 密钥:', timestampKey, '(策略: ' + keyStrategy + ')');
if (requestDecryptStrategy) {
console.log('📤 请求:', requestBody, '(解密策略: ' + requestDecryptStrategy + ')');
} else {
console.log('📤 请求:', requestBody);
}
if (responseDecryptStrategy) {
console.log('📥 响应:', decryptedResponse, '(解密策略: ' + responseDecryptStrategy + ')');
} else {
console.log('📥 响应:', decryptedResponse);
}
console.log('📍 UUID:', uuid);
console.groupEnd();
} catch (error) {
console.error('❌ Fetch 解密过程出错:', error);
}
return response;
}).catch((error) => {
console.error('❌ Fetch 请求失败:', error);
return Promise.reject(error);
});
};
console.log('✅ [页面上下文] Fetch 拦截已设置');
console.log('✅ [页面上下文] originalFetch 类型:', typeof originalFetch);
console.log('✅ [页面上下文] window.fetch:', typeof window.fetch);
// 验证拦截是否真的生效
setTimeout(function() {
const fetchStr = window.fetch.toString();
if (fetchStr.includes('clonedResponse') || fetchStr.includes('requestId')) {
console.log('✅ [页面上下文] Fetch 拦截验证成功');
} else {
console.error('❌ [页面上下文] Fetch 拦截验证失败,可能被覆盖');
console.error(' 当前 fetch 函数:', fetchStr.substring(0, 100));
}
}, 500);
})();
// 暴露 API 供 DevTools 面板使用
window.__XHR_DECRYPT_EXTENSION__ = {
getDecryptedRequests: function() {
return decryptedData.getRequests();
},
clearDecryptedRequests: function() {
decryptedData.clear();
console.log('✅ 已清空解密记录');
}
};
console.log('✅ [页面上下文] 拦截脚本初始化完成');
console.log('✅ [页面上下文] 已拦截 XHR:', typeof XMLHttpRequest !== 'undefined');
console.log('✅ [页面上下文] 已拦截 Fetch:', typeof fetch !== 'undefined');
// 测试一下拦截是否真的工作
setTimeout(function() {
console.log('🧪 [页面上下文] 测试:检查拦截状态');
console.log('🧪 [页面上下文] XMLHttpRequest.prototype.open:', typeof XMLHttpRequest.prototype.open);
console.log('🧪 [页面上下文] window.fetch:', typeof window.fetch);
// 尝试创建一个测试请求(仅用于验证)
try {
const testXhr = new XMLHttpRequest();
console.log('🧪 [页面上下文] 测试:可以创建 XMLHttpRequest 实例');
} catch (e) {
console.error('🧪 [页面上下文] 测试:无法创建 XMLHttpRequest:', e);
}
}, 1000);
})();
`;
// 注入到页面上下文
// 必须在页面脚本运行之前注入,否则无法拦截
function injectToPage() {
try {
// 方式1尝试注入到 head
if (document.head) {
document.head.appendChild(script.cloneNode(true));
console.log('✅ 拦截脚本已注入到 head');
return;
}
// 方式2注入到 documentElement
if (document.documentElement) {
document.documentElement.appendChild(script.cloneNode(true));
console.log('✅ 拦截脚本已注入到 documentElement');
return;
}
// 方式3如果都不行等待 DOM 加载
console.warn('⚠️ DOM 未准备好,等待加载...');
const checkInterval = setInterval(function () {
if (document.head || document.documentElement) {
clearInterval(checkInterval);
injectToPage();
}
}, 50);
// 超时保护
setTimeout(function () {
clearInterval(checkInterval);
console.error('❌ 注入超时DOM 可能无法加载');
}, 5000);
} catch (e) {
console.error('❌ 注入脚本失败:', e);
}
}
// 立即尝试注入(不等待)
try {
// 如果 DOM 已准备好,立即注入
if (document.head || document.documentElement) {
injectToPage();
} else {
// 如果还没准备好,使用多种方式等待
console.log('⏳ DOM 未准备好,准备注入...');
// 方式1等待 DOMContentLoaded
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function () {
console.log('📄 DOMContentLoaded 触发,开始注入');
injectToPage();
}, { once: true });
}
// 方式2也尝试立即注入某些浏览器允许
setTimeout(function () {
if (document.head || document.documentElement) {
console.log('⏱️ 延迟注入尝试');
injectToPage();
}
}, 0);
// 方式3监听 readystatechange
document.addEventListener('readystatechange', function () {
if (document.readyState !== 'loading') {
console.log('📄 readystatechange 触发readyState:', document.readyState);
injectToPage();
}
}, { once: true });
}
} catch (e) {
console.error('❌ 注入过程出错:', e);
}
// 在 Content Script 中监听来自页面上下文的事件
window.addEventListener('__XHR_DECRYPTED__', function (event) {
if (event.detail) {
decryptedRequests.push(event.detail);
if (decryptedRequests.length > 100) {
decryptedRequests.shift();
}
// 发送到 background
if (typeof chrome !== 'undefined' && chrome.runtime) {
chrome.runtime.sendMessage({
type: 'DECRYPTED_REQUEST',
data: event.detail
});
}
}
});
// 监听来自 popup 的消息
if (typeof chrome !== 'undefined' && chrome.runtime && chrome.runtime.onMessage) {
chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
if (message.action === 'getDecryptedRequests') {
// 直接返回 content script 中存储的数据
// content script 会从页面事件中接收更新
sendResponse({ data: decryptedRequests });
return true;
} else if (message.action === 'clearDecryptedRequests') {
decryptedRequests = [];
// 清除页面上下文的记录
const clearScript = document.createElement('script');
clearScript.textContent = `
(function() {
if (window.__XHR_DECRYPT_EXTENSION__) {
window.__XHR_DECRYPT_EXTENSION__.clearDecryptedRequests();
}
})();
`;
document.documentElement.appendChild(clearScript);
clearScript.remove();
sendResponse({ success: true });
}
});
}
// 暴露 API 供 popup 使用Content Script 上下文)
window.__XHR_DECRYPT_EXTENSION__ = {
getDecryptedRequests: function () {
// 返回 content script 中存储的数据
return decryptedRequests;
},
clearDecryptedRequests: function () {
decryptedRequests = [];
// 清除页面上下文的记录
const clearScript = document.createElement('script');
clearScript.textContent = `
(function() {
if (window.__XHR_DECRYPT_EXTENSION__) {
window.__XHR_DECRYPT_EXTENSION__.clearDecryptedRequests();
}
})();
`;
document.documentElement.appendChild(clearScript);
clearScript.remove();
}
};
console.log('✅ Content Script 已启动');
console.log('📊 Content Script 当前记录数:', decryptedRequests.length);
console.log('📊 Content Script document.readyState:', document.readyState);
console.log('📊 Content Script 准备注入拦截脚本...');
console.log('📊 Content Script window.location:', window.location.href);
// 立即检查是否已经注入成功(某些情况下可能已经注入)
try {
const testScript = document.createElement('script');
testScript.textContent = `
(function() {
if (window.__XHR_DECRYPT_EXTENSION__) {
console.log('✅ [页面上下文] 拦截对象已存在');
} else {
console.warn('⚠️ [页面上下文] 拦截对象不存在');
}
if (window.__XHR_DECRYPT_DATA__) {
console.log('✅ [页面上下文] 数据对象已存在');
} else {
console.warn('⚠️ [页面上下文] 数据对象不存在');
}
})();
`;
if (document.head || document.documentElement) {
(document.head || document.documentElement).appendChild(testScript);
testScript.remove();
}
} catch (e) {
console.error('❌ 检查注入状态失败:', e);
}
// 延迟检查注入是否成功
setTimeout(function () {
// 通过 DevTools API 检查
if (typeof chrome !== 'undefined' && chrome.devtools && chrome.devtools.inspectedWindow) {
chrome.devtools.inspectedWindow.eval('typeof window.__XHR_DECRYPT_EXTENSION__', function (result, isException) {
if (isException) {
console.warn('⚠️ 无法访问页面上下文,可能注入失败。错误:', result);
} else {
if (result === 'object') {
console.log('✅ 拦截脚本注入成功,页面上下文对象存在');
} else {
console.warn('⚠️ 拦截脚本可能未注入成功,页面上下文对象类型:', result);
}
}
});
} else {
// 如果没有 DevTools使用其他方式检查
const checkScript = document.createElement('script');
checkScript.textContent = `
(function() {
console.log('🔍 [页面上下文] 检查拦截状态...');
console.log('🔍 [页面上下文] __XHR_DECRYPT_EXTENSION__:', typeof window.__XHR_DECRYPT_EXTENSION__);
console.log('🔍 [页面上下文] __XHR_DECRYPT_DATA__:', typeof window.__XHR_DECRYPT_DATA__);
console.log('🔍 [页面上下文] XMLHttpRequest:', typeof XMLHttpRequest);
console.log('🔍 [页面上下文] fetch:', typeof fetch);
// 检查拦截是否真的工作
if (XMLHttpRequest.prototype.open.toString().includes('_method')) {
console.log('✅ [页面上下文] XHR 拦截已生效');
} else {
console.warn('⚠️ [页面上下文] XHR 拦截可能未生效');
}
if (window.fetch.toString().includes('clonedResponse') || window.fetch.toString().includes('requestId')) {
console.log('✅ [页面上下文] Fetch 拦截已生效');
} else {
console.warn('⚠️ [页面上下文] Fetch 拦截可能未生效');
}
})();
`;
if (document.head || document.documentElement) {
(document.head || document.documentElement).appendChild(checkScript);
checkScript.remove();
}
}
}, 3000);
}) ();