// General Auto - Injected Script (function() { 'use strict'; console.log('General Auto Injected script 已加载'); // 存储原始方法 const originalXHR = window.XMLHttpRequest; const originalFetch = window.fetch; const originalOpen = window.open; // 请求拦截器配置 window.GeneralAutoConfig = { interceptXHR: true, interceptFetch: true, logRequests: true, requestCallbacks: [], responseCallbacks: [] }; // 拦截 XMLHttpRequest window.XMLHttpRequest = function() { const xhr = new originalXHR(); const config = window.GeneralAutoConfig; if (!config.interceptXHR) return xhr; const originalOpen = xhr.open; const originalSend = xhr.send; const originalSetRequestHeader = xhr.setRequestHeader; let requestData = { method: '', url: '', headers: {}, body: null, timestamp: Date.now() }; xhr.open = function(method, url) { requestData.method = method; requestData.url = url; return originalOpen.apply(this, arguments); }; xhr.setRequestHeader = function(name, value) { requestData.headers[name] = value; return originalSetRequestHeader.apply(this, arguments); }; xhr.send = function(body) { requestData.body = body; // 请求前回调 config.requestCallbacks.forEach(callback => { try { callback(requestData); } catch (e) { console.error('Request callback error:', e); } }); // 监听响应 this.addEventListener('load', function() { const responseData = { ...requestData, status: this.status, statusText: this.statusText, responseHeaders: this.getAllResponseHeaders(), response: this.response, responseText: this.responseText, responseType: this.responseType, responseURL: this.responseURL }; // 响应后回调 config.responseCallbacks.forEach(callback => { try { callback(responseData); } catch (e) { console.error('Response callback error:', e); } }); // 发送到 background if (config.logRequests) { window.postMessage({ type: 'FROM_PAGE', action: 'logRequest', data: { type: 'xhr', method: responseData.method, url: responseData.url, status: responseData.status, requestHeaders: responseData.headers, requestBody: responseData.body, responseHeaders: responseData.responseHeaders, response: responseData.responseText } }, '*'); } }); this.addEventListener('error', function() { console.error('XHR Error:', requestData.url); }); return originalSend.apply(this, arguments); }; return xhr; }; // 拦截 Fetch window.fetch = function() { const config = window.GeneralAutoConfig; if (!config.interceptFetch) { return originalFetch.apply(this, arguments); } const url = arguments[0]; const options = arguments[1] || {}; const requestData = { method: options.method || 'GET', url: typeof url === 'string' ? url : url.url, headers: options.headers || {}, body: options.body, timestamp: Date.now() }; // 请求前回调 config.requestCallbacks.forEach(callback => { try { callback(requestData); } catch (e) { console.error('Request callback error:', e); } }); return originalFetch.apply(this, arguments).then(response => { const clonedResponse = response.clone(); clonedResponse.text().then(body => { const responseData = { ...requestData, status: response.status, statusText: response.statusText, headers: Object.fromEntries(response.headers.entries()), response: body, responseURL: response.url }; // 响应后回调 config.responseCallbacks.forEach(callback => { try { callback(responseData); } catch (e) { console.error('Response callback error:', e); } }); // 发送到 background if (config.logRequests) { window.postMessage({ type: 'FROM_PAGE', action: 'logRequest', data: { type: 'fetch', method: responseData.method, url: responseData.url, status: responseData.status, requestHeaders: responseData.headers, requestBody: responseData.body, responseHeaders: responseData.headers, response: body } }, '*'); } }); return response; }); }; // 提供全局自动化工具 API window.AutomationUtils = { // 模拟人类输入 humanInput: function(element, text, minDelay = 50, maxDelay = 150) { return new Promise((resolve) => { element.focus(); let index = 0; const type = () => { if (index < text.length) { const char = text[index]; // 触发键盘事件 const keydownEvent = new KeyboardEvent('keydown', { key: char, code: `Key${char.toUpperCase()}`, bubbles: true, cancelable: true }); const keypressEvent = new KeyboardEvent('keypress', { key: char, code: `Key${char.toUpperCase()}`, bubbles: true, cancelable: true }); const keyupEvent = new KeyboardEvent('keyup', { key: char, code: `Key${char.toUpperCase()}`, bubbles: true, cancelable: true }); element.dispatchEvent(keydownEvent); element.dispatchEvent(keypressEvent); element.value += char; element.dispatchEvent(new Event('input', { bubbles: true })); element.dispatchEvent(keyupEvent); index++; const delay = minDelay + Math.random() * (maxDelay - minDelay); setTimeout(type, delay); } else { element.dispatchEvent(new Event('change', { bubbles: true })); element.blur(); resolve(); } }; setTimeout(type, 100); }); }, // 模拟人类点击 humanClick: function(element, options = {}) { return new Promise((resolve) => { const rect = element.getBoundingClientRect(); const x = rect.left + (options.offsetX || rect.width * (0.3 + Math.random() * 0.4)); const y = rect.top + (options.offsetY || rect.height * (0.3 + Math.random() * 0.4)); // 滚动到元素 element.scrollIntoView({ behavior: 'smooth', block: 'center' }); setTimeout(() => { // 鼠标移动 const mousemoveEvent = new MouseEvent('mousemove', { view: window, bubbles: true, cancelable: true, clientX: x, clientY: y }); element.dispatchEvent(mousemoveEvent); setTimeout(() => { // 鼠标按下 const mousedownEvent = new MouseEvent('mousedown', { view: window, bubbles: true, cancelable: true, clientX: x, clientY: y, button: 0 }); element.dispatchEvent(mousedownEvent); setTimeout(() => { // 鼠标抬起 const mouseupEvent = new MouseEvent('mouseup', { view: window, bubbles: true, cancelable: true, clientX: x, clientY: y, button: 0 }); element.dispatchEvent(mouseupEvent); // 点击 const clickEvent = new MouseEvent('click', { view: window, bubbles: true, cancelable: true, clientX: x, clientY: y, button: 0 }); element.dispatchEvent(clickEvent); resolve(); }, 50 + Math.random() * 50); }, 50 + Math.random() * 50); }, 200 + Math.random() * 300); }); }, // 等待元素出现 waitForElement: function(selector, timeout = 10000, checkVisible = true) { return new Promise((resolve, reject) => { const check = () => { const element = document.querySelector(selector); if (element) { if (!checkVisible) { resolve(element); return true; } const rect = element.getBoundingClientRect(); const isVisible = rect.width > 0 && rect.height > 0 && window.getComputedStyle(element).visibility !== 'hidden' && window.getComputedStyle(element).display !== 'none'; if (isVisible) { resolve(element); return true; } } return false; }; if (check()) return; const observer = new MutationObserver(() => { if (check()) { observer.disconnect(); } }); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); setTimeout(() => { observer.disconnect(); reject(new Error(`等待元素超时: ${selector}`)); }, timeout); }); }, // 等待元素消失 waitForElementRemoved: function(selector, timeout = 10000) { return new Promise((resolve, reject) => { const check = () => { const element = document.querySelector(selector); if (!element) { resolve(); return true; } const rect = element.getBoundingClientRect(); const isHidden = rect.width === 0 || rect.height === 0 || window.getComputedStyle(element).visibility === 'hidden' || window.getComputedStyle(element).display === 'none'; if (isHidden) { resolve(); return true; } return false; }; if (check()) return; const observer = new MutationObserver(() => { if (check()) { observer.disconnect(); } }); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); setTimeout(() => { observer.disconnect(); reject(new Error(`等待元素消失超时: ${selector}`)); }, timeout); }); }, // 随机延迟 randomDelay: function(min = 100, max = 500) { return new Promise(resolve => { setTimeout(resolve, min + Math.random() * (max - min)); }); }, // 获取所有元素 getElements: function(selector) { return Array.from(document.querySelectorAll(selector)); }, // 监听请求 onRequest: function(callback) { window.GeneralAutoConfig.requestCallbacks.push(callback); }, // 监听响应 onResponse: function(callback) { window.GeneralAutoConfig.responseCallbacks.push(callback); }, // 清除所有回调 clearCallbacks: function() { window.GeneralAutoConfig.requestCallbacks = []; window.GeneralAutoConfig.responseCallbacks = []; } }; // 简写 window.AU = window.AutomationUtils; console.log('AutomationUtils API 已就绪'); })();