// General Auto - Background Service Worker console.log('General Auto 后台服务已启动'); // 任务队列和状态管理 const state = { taskQueue: [], isProcessing: false, requestLogs: [], maxLogs: 100 }; // 监听来自 content script 的消息 chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { console.log('收到消息:', request); switch (request.action) { case 'executeTask': executeTask(request.task, sender.tab.id) .then(result => sendResponse({ success: true, data: result })) .catch(error => sendResponse({ success: false, error: error.message })); return true; case 'executeScript': executeScript(request.code, sender.tab.id) .then(result => sendResponse({ success: true, data: result })) .catch(error => sendResponse({ success: false, error: error.message })); return true; case 'getCookies': getCookies(request.url) .then(cookies => sendResponse({ success: true, cookies })) .catch(error => sendResponse({ success: false, error: error.message })); return true; case 'setCookies': setCookies(request.cookies) .then(() => sendResponse({ success: true })) .catch(error => sendResponse({ success: false, error: error.message })); return true; case 'clearCookies': clearCookies(request.url) .then(() => sendResponse({ success: true })) .catch(error => sendResponse({ success: false, error: error.message })); return true; case 'navigateTo': navigateTo(request.url, sender.tab.id) .then(() => sendResponse({ success: true })) .catch(error => sendResponse({ success: false, error: error.message })); return true; case 'getRequestLogs': sendResponse({ success: true, logs: state.requestLogs }); break; case 'clearRequestLogs': state.requestLogs = []; sendResponse({ success: true }); break; case 'getStatus': sendResponse({ success: true, status: { taskCount: state.taskQueue.length, isProcessing: state.isProcessing, requestLogCount: state.requestLogs.length } }); break; case 'logRequest': logRequest(request.data); sendResponse({ success: true }); break; default: sendResponse({ success: false, error: '未知操作' }); } }); // 执行自动化任务 async function executeTask(task, tabId) { try { const result = await chrome.scripting.executeScript({ target: { tabId: tabId }, func: executeTaskInPage, args: [task] }); return result[0].result; } catch (error) { console.error('执行任务失败:', error); throw error; } } // 在页面中执行的任务函数 function executeTaskInPage(task) { const { type, selector, action, value, timeout = 10000, waitVisible = true } = task; return new Promise((resolve, reject) => { const timer = setTimeout(() => { reject(new Error(`任务执行超时: ${timeout}ms`)); }, timeout); try { switch (type) { case 'click': waitForElement(selector, timeout, waitVisible).then(el => { el.click(); clearTimeout(timer); resolve({ success: true, message: '点击成功' }); }).catch(err => { clearTimeout(timer); reject(err); }); break; case 'input': waitForElement(selector, timeout, waitVisible).then(el => { el.value = value; el.dispatchEvent(new Event('input', { bubbles: true })); el.dispatchEvent(new Event('change', { bubbles: true })); clearTimeout(timer); resolve({ success: true, message: '输入成功' }); }).catch(err => { clearTimeout(timer); reject(err); }); break; case 'humanInput': waitForElement(selector, timeout, waitVisible).then(el => { humanTypeInput(el, value).then(() => { clearTimeout(timer); resolve({ success: true, message: '人类输入成功' }); }); }).catch(err => { clearTimeout(timer); reject(err); }); break; case 'getText': waitForElement(selector, timeout, waitVisible).then(el => { clearTimeout(timer); resolve({ success: true, text: el.textContent.trim() }); }).catch(err => { clearTimeout(timer); reject(err); }); break; case 'getAttribute': waitForElement(selector, timeout, waitVisible).then(el => { const attrValue = el.getAttribute(value); clearTimeout(timer); resolve({ success: true, value: attrValue }); }).catch(err => { clearTimeout(timer); reject(err); }); break; case 'scroll': window.scrollBy({ top: value.y || 0, left: value.x || 0, behavior: 'smooth' }); clearTimeout(timer); resolve({ success: true, message: '滚动成功' }); break; case 'scrollToElement': waitForElement(selector, timeout, false).then(el => { el.scrollIntoView({ behavior: 'smooth', block: 'center' }); clearTimeout(timer); resolve({ success: true, message: '滚动到元素成功' }); }).catch(err => { clearTimeout(timer); reject(err); }); break; case 'wait': setTimeout(() => { clearTimeout(timer); resolve({ success: true, message: `等待 ${value}ms 完成` }); }, value); break; case 'waitForElement': waitForElement(selector, timeout, waitVisible).then(el => { clearTimeout(timer); resolve({ success: true, message: '元素已出现' }); }).catch(err => { clearTimeout(timer); reject(err); }); break; case 'evaluate': try { const result = eval(value); clearTimeout(timer); resolve({ success: true, result: result }); } catch (err) { clearTimeout(timer); reject(err); } break; default: clearTimeout(timer); reject(new Error(`未知任务类型: ${type}`)); } } catch (error) { clearTimeout(timer); reject(error); } }); // 等待元素出现 function waitForElement(selector, timeout, checkVisible) { 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); }); } // 模拟人类输入 function humanTypeInput(element, text, minDelay = 50, maxDelay = 150) { return new Promise((resolve) => { let index = 0; const type = () => { if (index < text.length) { element.value += text[index]; element.dispatchEvent(new Event('input', { bubbles: true })); index++; const delay = minDelay + Math.random() * (maxDelay - minDelay); setTimeout(type, delay); } else { element.dispatchEvent(new Event('change', { bubbles: true })); resolve(); } }; type(); }); } } // 执行自定义脚本 async function executeScript(code, tabId) { try { const result = await chrome.scripting.executeScript({ target: { tabId: tabId }, func: (code) => eval(code), args: [code] }); return result[0].result; } catch (error) { console.error('执行脚本失败:', error); throw error; } } // Cookie 管理 async function getCookies(url) { if (url) { return await chrome.cookies.getAll({ url }); } else { return await chrome.cookies.getAll({}); } } async function setCookies(cookies) { for (const cookie of cookies) { try { await chrome.cookies.set(cookie); } catch (error) { console.error('设置 Cookie 失败:', cookie, error); } } } async function clearCookies(url) { let cookies; if (url) { cookies = await chrome.cookies.getAll({ url }); } else { cookies = await chrome.cookies.getAll({}); } for (const cookie of cookies) { const protocol = cookie.secure ? 'https:' : 'http:'; const cookieUrl = `${protocol}//${cookie.domain}${cookie.path}`; await chrome.cookies.remove({ url: cookieUrl, name: cookie.name }); } } // 导航到指定 URL async function navigateTo(url, tabId) { await chrome.tabs.update(tabId, { url: url }); } // 记录请求 function logRequest(data) { state.requestLogs.push({ ...data, timestamp: Date.now() }); // 限制日志数量 if (state.requestLogs.length > state.maxLogs) { state.requestLogs.shift(); } } // 监听标签页更新 chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { if (changeInfo.status === 'complete') { console.log('页面加载完成:', tab.url); } }); // 监听网络请求 chrome.webRequest.onBeforeRequest.addListener( (details) => { // 可以在这里拦截和修改请求 if (details.type === 'xmlhttprequest' || details.type === 'fetch') { console.log('API 请求:', details.url); } }, { urls: [""] }, [] ); // 监听响应头 chrome.webRequest.onCompleted.addListener( (details) => { if (details.type === 'xmlhttprequest' || details.type === 'fetch') { console.log('API 响应:', details.url, details.statusCode); } }, { urls: [""] }, [] );