|
|
|
@ -58,86 +58,83 @@ const windowProxyMap = new Map(); |
|
|
|
|
|
|
|
// 修改代理设置函数
|
|
|
|
function setProxyForWindow(proxyConfig, windowId, callback) { |
|
|
|
const maxRetries = 3; |
|
|
|
let retryCount = 0; |
|
|
|
|
|
|
|
function trySetProxy() { |
|
|
|
console.log(`窗口 ${windowId} 设置代理尝试 ${retryCount + 1}/${maxRetries}:`, proxyConfig); |
|
|
|
|
|
|
|
// 存储当前窗口的代理设置
|
|
|
|
windowProxyMap.set(windowId, proxyConfig); |
|
|
|
|
|
|
|
// 设置新的代理
|
|
|
|
const config = { |
|
|
|
value: { |
|
|
|
mode: "fixed_servers", |
|
|
|
rules: { |
|
|
|
singleProxy: { |
|
|
|
scheme: "http", |
|
|
|
host: proxyConfig.host, |
|
|
|
port: parseInt(proxyConfig.port) |
|
|
|
}, |
|
|
|
bypassList: [ |
|
|
|
"localhost", |
|
|
|
"127.0.0.1", |
|
|
|
"<local>" |
|
|
|
] |
|
|
|
} |
|
|
|
}, |
|
|
|
scope: "regular" |
|
|
|
console.log(`设置窗口 ${windowId} 的代理:`, { |
|
|
|
host: proxyConfig.host, |
|
|
|
port: proxyConfig.port, |
|
|
|
username: proxyConfig.username |
|
|
|
}); |
|
|
|
|
|
|
|
// 存储当前窗口的代理设置
|
|
|
|
windowProxyMap.set(windowId, proxyConfig); |
|
|
|
|
|
|
|
// 设置认证监听器
|
|
|
|
const authHandler = function(details) { |
|
|
|
return { |
|
|
|
authCredentials: { |
|
|
|
username: proxyConfig.username, |
|
|
|
password: proxyConfig.password |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
// 移除之前的监听器(如果存在)
|
|
|
|
try { |
|
|
|
chrome.webRequest.onAuthRequired.removeListener(authHandler); |
|
|
|
} catch (e) {} |
|
|
|
|
|
|
|
// 添加新的监听器
|
|
|
|
chrome.webRequest.onAuthRequired.addListener( |
|
|
|
authHandler, |
|
|
|
{ urls: ["<all_urls>"] }, |
|
|
|
["asyncBlocking"] |
|
|
|
); |
|
|
|
|
|
|
|
chrome.proxy.settings.set( |
|
|
|
config, |
|
|
|
function() { |
|
|
|
if (chrome.runtime.lastError) { |
|
|
|
console.error('设置代理失败:', chrome.runtime.lastError); |
|
|
|
handleError(chrome.runtime.lastError); |
|
|
|
return; |
|
|
|
// 设置代理配置
|
|
|
|
const config = { |
|
|
|
value: { |
|
|
|
mode: "fixed_servers", |
|
|
|
rules: { |
|
|
|
singleProxy: { |
|
|
|
scheme: "http", |
|
|
|
host: proxyConfig.host, |
|
|
|
port: parseInt(proxyConfig.port) |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
scope: "regular" |
|
|
|
}; |
|
|
|
|
|
|
|
// 设置代理
|
|
|
|
chrome.proxy.settings.set( |
|
|
|
config, |
|
|
|
function() { |
|
|
|
if (chrome.runtime.lastError) { |
|
|
|
console.error('设置代理失败:', chrome.runtime.lastError); |
|
|
|
callback(chrome.runtime.lastError); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 验证代理设置
|
|
|
|
chrome.proxy.settings.get( |
|
|
|
{ incognito: false }, |
|
|
|
function(config) { |
|
|
|
console.log(`窗口 ${windowId} 当前代理配置:`, config); |
|
|
|
if (config.value.mode === "fixed_servers") { |
|
|
|
// 只刷新当前窗口的标签页
|
|
|
|
chrome.tabs.query({ windowId: windowId }, function(tabs) { |
|
|
|
let refreshedCount = 0; |
|
|
|
if (tabs.length === 0) { |
|
|
|
callback(null, true); |
|
|
|
return; |
|
|
|
} |
|
|
|
console.log(`窗口 ${windowId} 代理设置成功`); |
|
|
|
|
|
|
|
// 刷新标签页
|
|
|
|
chrome.tabs.query({ windowId: windowId }, function(tabs) { |
|
|
|
if (tabs.length === 0) { |
|
|
|
callback(null, true); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
tabs.forEach(function(tab) { |
|
|
|
chrome.tabs.reload(tab.id, { bypassCache: true }, function() { |
|
|
|
refreshedCount++; |
|
|
|
if (refreshedCount === tabs.length) { |
|
|
|
callback(null, true); |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|
} else { |
|
|
|
handleError(new Error('代理设置验证失败')); |
|
|
|
let refreshedCount = 0; |
|
|
|
tabs.forEach(function(tab) { |
|
|
|
chrome.tabs.reload(tab.id, { bypassCache: true }, function() { |
|
|
|
refreshedCount++; |
|
|
|
if (refreshedCount === tabs.length) { |
|
|
|
callback(null, true); |
|
|
|
} |
|
|
|
} |
|
|
|
); |
|
|
|
} |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
function handleError(error) { |
|
|
|
if (retryCount < maxRetries - 1) { |
|
|
|
retryCount++; |
|
|
|
setTimeout(trySetProxy, 2000); |
|
|
|
} else { |
|
|
|
callback(error); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
trySetProxy(); |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
// 消息监听器
|
|
|
|
@ -219,7 +216,7 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { |
|
|
|
}) |
|
|
|
.catch(error => { |
|
|
|
console.error('登录请求出错:', error); |
|
|
|
sendResponse({ status: 'error', message: '登录请求出错,请检查网络连接或稍后重试。' }); |
|
|
|
sendResponse({ status: 'error', message: '登录请出错,请检查网络连接或稍后重试。' }); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
@ -245,14 +242,14 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { |
|
|
|
console.error('设置代理失败:', error); |
|
|
|
sendResponse({ success: false, error: error.message }); |
|
|
|
} else { |
|
|
|
console.log('代理已设置到新创建的无痕窗口'); |
|
|
|
console.log('代理已设置到新创建无痕窗口'); |
|
|
|
sendResponse({ success: true }); |
|
|
|
} |
|
|
|
} |
|
|
|
); |
|
|
|
}, 1000); |
|
|
|
} else { |
|
|
|
console.error('创建窗口失败'); |
|
|
|
console.error('建窗口失败'); |
|
|
|
sendResponse({ success: false, error: '创建窗口失败' }); |
|
|
|
} |
|
|
|
}); |
|
|
|
@ -266,46 +263,84 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { |
|
|
|
const proxyList = request.proxyList; |
|
|
|
console.log('可用代理列表:', proxyList); |
|
|
|
|
|
|
|
if (proxyList.length < incognitoWindows.length) { |
|
|
|
if (proxyList.length === 0) { |
|
|
|
sendResponse({ |
|
|
|
success: false, |
|
|
|
error: `代理数量不足,需要 ${incognitoWindows.length} 个代理,但只有 ${proxyList.length} 个` |
|
|
|
error: '没有可用的代理' |
|
|
|
}); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
let completedCount = 0; |
|
|
|
let errors = []; |
|
|
|
let currentIndex = 0; |
|
|
|
|
|
|
|
// 处理下一个窗口
|
|
|
|
function processNextWindow() { |
|
|
|
if (currentIndex >= incognitoWindows.length) { |
|
|
|
checkComplete(); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 为每个窗口单独设置代理
|
|
|
|
incognitoWindows.forEach((window, index) => { |
|
|
|
const proxy = proxyList[index]; |
|
|
|
const [host, port] = proxy.split(':'); |
|
|
|
const window = incognitoWindows[currentIndex]; |
|
|
|
|
|
|
|
// 检查窗口是否已经有代理设置
|
|
|
|
const existingProxy = windowProxyMap.get(window.id); |
|
|
|
if (existingProxy) { |
|
|
|
console.log(`窗口 ${window.id} 已有代理设置,跳过:`, { |
|
|
|
host: existingProxy.host, |
|
|
|
port: existingProxy.port, |
|
|
|
username: existingProxy.username |
|
|
|
}); |
|
|
|
completedCount++; |
|
|
|
currentIndex++; |
|
|
|
processNextWindow(); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if (!host || !port) { |
|
|
|
errors.push(`代理格式错误: ${proxy}`); |
|
|
|
// 使用循环方式获取代理配置
|
|
|
|
const proxyIndex = currentIndex % proxyList.length; |
|
|
|
const proxy = proxyList[proxyIndex]; |
|
|
|
|
|
|
|
if (!proxy || !proxy.host || !proxy.port) { |
|
|
|
errors.push(`代理配置无效: ${JSON.stringify(proxy)}`); |
|
|
|
completedCount++; |
|
|
|
checkComplete(); |
|
|
|
currentIndex++; |
|
|
|
processNextWindow(); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 为每个窗口设置代理时先激活该窗口
|
|
|
|
console.log(`窗口 ${window.id} 使用第 ${proxyIndex + 1} 个代理 (总共 ${proxyList.length} 个)`); |
|
|
|
|
|
|
|
// 为窗口设置代理
|
|
|
|
chrome.windows.update(window.id, { focused: true }, () => { |
|
|
|
setTimeout(() => { |
|
|
|
setProxyForWindow( |
|
|
|
{ host, port: parseInt(port) }, |
|
|
|
proxy, |
|
|
|
window.id, |
|
|
|
(error, success) => { |
|
|
|
if (error) { |
|
|
|
console.error(`窗口 ${window.id} 设置代理失败:`, error); |
|
|
|
errors.push(`窗口 ${window.id} 设置代理失败: ${error.message}`); |
|
|
|
} else { |
|
|
|
console.log(`窗口 ${window.id} 使用代理:`, { |
|
|
|
host: proxy.host, |
|
|
|
port: proxy.port, |
|
|
|
username: proxy.username, |
|
|
|
password: proxy.password |
|
|
|
}); |
|
|
|
} |
|
|
|
completedCount++; |
|
|
|
checkComplete(); |
|
|
|
currentIndex++; |
|
|
|
setTimeout(processNextWindow, 1000); // 等待1秒后处理下一个窗口
|
|
|
|
} |
|
|
|
); |
|
|
|
}, index * 3000); // 每个窗口间隔3秒
|
|
|
|
}, 1000); |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
// 开始处理第一个窗口
|
|
|
|
processNextWindow(); |
|
|
|
|
|
|
|
function checkComplete() { |
|
|
|
if (completedCount === incognitoWindows.length) { |
|
|
|
@ -317,33 +352,138 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { |
|
|
|
} else { |
|
|
|
sendResponse({ |
|
|
|
success: true, |
|
|
|
message: `已为 ${incognitoWindows.length} 个无痕窗口设置独立代理` |
|
|
|
message: `已为 ${incognitoWindows.length} 个无痕窗口设置代理` |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
sendResponse({ success: false, error: '未找到无痕窗��' }); |
|
|
|
sendResponse({ success: false, error: '未找到无痕窗口' }); |
|
|
|
} |
|
|
|
}); |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
if (request.action === 'clearProxy') { |
|
|
|
chrome.proxy.settings.clear( |
|
|
|
{ |
|
|
|
scope: "regular" |
|
|
|
}, |
|
|
|
() => { |
|
|
|
if (chrome.runtime.lastError) { |
|
|
|
console.error('清除代理失败:', chrome.runtime.lastError); |
|
|
|
sendResponse({ success: false, error: chrome.runtime.lastError.message }); |
|
|
|
} else { |
|
|
|
console.log('代理设置已完全清除'); |
|
|
|
sendResponse({ success: true }); |
|
|
|
try { |
|
|
|
// 清除代理设置
|
|
|
|
chrome.proxy.settings.clear( |
|
|
|
{ scope: "regular" }, |
|
|
|
async function() { |
|
|
|
if (chrome.runtime.lastError) { |
|
|
|
console.error('清除代理设置失败:', chrome.runtime.lastError); |
|
|
|
sendResponse({ success: false, error: chrome.runtime.lastError.message }); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
console.log('代理设置已清除'); |
|
|
|
|
|
|
|
try { |
|
|
|
// 获取所有窗口
|
|
|
|
const windows = await new Promise((resolve) => { |
|
|
|
chrome.windows.getAll({ |
|
|
|
populate: true |
|
|
|
}, resolve); |
|
|
|
}); |
|
|
|
|
|
|
|
// 清除代理映射
|
|
|
|
windowProxyMap.clear(); |
|
|
|
console.log('代理映射已清除'); |
|
|
|
|
|
|
|
// 清除认证缓存
|
|
|
|
const removeCache = async () => { |
|
|
|
try { |
|
|
|
await chrome.browsingData.remove({ |
|
|
|
"since": 0 |
|
|
|
}, { |
|
|
|
"cache": true, |
|
|
|
"cookies": true, |
|
|
|
"passwords": true, |
|
|
|
"webSQL": true, |
|
|
|
"serviceWorkers": true, |
|
|
|
"indexedDB": true |
|
|
|
}); |
|
|
|
console.log('认证缓存已清除'); |
|
|
|
} catch (error) { |
|
|
|
console.error('清除认证缓存失败:', error); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
await removeCache(); |
|
|
|
|
|
|
|
// 刷新所有无痕窗口的标签页
|
|
|
|
for (const window of windows) { |
|
|
|
if (window.incognito) { |
|
|
|
console.log(`刷新无痕窗口 ${window.id} 的标签页`); |
|
|
|
for (const tab of window.tabs) { |
|
|
|
try { |
|
|
|
// 先导航到空白页面
|
|
|
|
await new Promise((resolve) => { |
|
|
|
chrome.tabs.update(tab.id, { url: 'about:blank' }, resolve); |
|
|
|
}); |
|
|
|
await new Promise(resolve => setTimeout(resolve, 500)); |
|
|
|
|
|
|
|
// 然后重新加载原始URL
|
|
|
|
await new Promise((resolve) => { |
|
|
|
chrome.tabs.reload(tab.id, { bypassCache: true }, resolve); |
|
|
|
}); |
|
|
|
// 添加短暂延迟,避免同时刷新太多标签页
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 500)); |
|
|
|
} catch (error) { |
|
|
|
console.error(`刷新标签页 ${tab.id} 失败:`, error); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
sendResponse({ |
|
|
|
success: true, |
|
|
|
message: '已清除所有代理设置、认证缓存并刷新标签页' |
|
|
|
}); |
|
|
|
} catch (error) { |
|
|
|
console.error('刷新标签页时出错:', error); |
|
|
|
sendResponse({ |
|
|
|
success: false, |
|
|
|
error: '清除代理成功但刷新标签页失败: ' + error.message |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
); |
|
|
|
} catch (error) { |
|
|
|
console.error('清除代理时出错:', error); |
|
|
|
sendResponse({ success: false, error: error.message }); |
|
|
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
if (request.action === 'getCurrentProxy') { |
|
|
|
try { |
|
|
|
const windowId = request.windowId; |
|
|
|
const proxyConfig = windowProxyMap.get(windowId); |
|
|
|
|
|
|
|
if (proxyConfig) { |
|
|
|
sendResponse({ |
|
|
|
success: true, |
|
|
|
proxy: { |
|
|
|
host: proxyConfig.host, |
|
|
|
port: proxyConfig.port, |
|
|
|
username: proxyConfig.username |
|
|
|
// 出于安全考虑,不返回密码
|
|
|
|
} |
|
|
|
}); |
|
|
|
} else { |
|
|
|
sendResponse({ |
|
|
|
success: true, |
|
|
|
proxy: null |
|
|
|
}); |
|
|
|
} |
|
|
|
); |
|
|
|
} catch (error) { |
|
|
|
console.error('获取代理信息失败:', error); |
|
|
|
sendResponse({ |
|
|
|
success: false, |
|
|
|
error: error.message |
|
|
|
}); |
|
|
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
@ -356,7 +496,7 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { |
|
|
|
}); |
|
|
|
|
|
|
|
chrome.windows.onCreated.addListener((window) => { |
|
|
|
console.log('新窗口创建:', { |
|
|
|
console.log('新窗口创:', { |
|
|
|
id: window.id, |
|
|
|
incognito: window.incognito, |
|
|
|
type: window.type, |
|
|
|
@ -375,21 +515,23 @@ chrome.tabs.onCreated.addListener((tab) => { |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
// 修改错误监听器,添加更多需要忽略的错误类型
|
|
|
|
// 修改错误监听器,添加更多需要忽略的误类型
|
|
|
|
chrome.webRequest.onErrorOccurred.addListener( |
|
|
|
function(details) { |
|
|
|
// 扩展需要忽略的错误类型列表
|
|
|
|
const ignoredErrors = [ |
|
|
|
'net::ERR_ABORTED', // 请求中断
|
|
|
|
'net::ERR_NETWORK_CHANGED', // 网络变化
|
|
|
|
'net::ERR_CONNECTION_CLOSED', // 连接关闭
|
|
|
|
'net::ERR_CACHE_MISS', // 缓存未命中
|
|
|
|
'net::ERR_EMPTY_RESPONSE', // 空响应
|
|
|
|
'net::ERR_FAILED', // 一般性失败
|
|
|
|
'net::ERR_TIMED_OUT' // 超时
|
|
|
|
'net::ERR_ABORTED', // 请求中断
|
|
|
|
'net::ERR_NETWORK_CHANGED', // 网络变化
|
|
|
|
'net::ERR_CONNECTION_CLOSED', // 连接关闭
|
|
|
|
'net::ERR_CACHE_MISS', // 缓存未命中
|
|
|
|
'net::ERR_EMPTY_RESPONSE', // 空响应
|
|
|
|
'net::ERR_FAILED', // 一般性失败
|
|
|
|
'net::ERR_TIMED_OUT', // 超时
|
|
|
|
'net::ERR_TOO_MANY_RETRIES', // 重试次数过多
|
|
|
|
'net::ERR_TUNNEL_CONNECTION_FAILED' // 隧道连接失败
|
|
|
|
]; |
|
|
|
|
|
|
|
// 忽略的资源类型
|
|
|
|
// 略的资源类型
|
|
|
|
const ignoredResourceTypes = [ |
|
|
|
'font', // 字体文件
|
|
|
|
'image', // 图片
|
|
|
|
@ -455,25 +597,16 @@ chrome.windows.onFocusChanged.addListener((windowId) => { |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
// 添加窗口焦点变化监听器
|
|
|
|
// 修改窗口焦点变化监听器
|
|
|
|
chrome.windows.onFocusChanged.addListener((windowId) => { |
|
|
|
if (windowId !== chrome.windows.WINDOW_ID_NONE) { |
|
|
|
const proxyConfig = windowProxyMap.get(windowId); |
|
|
|
if (proxyConfig) { |
|
|
|
console.log(`窗口 ${windowId} 获得焦点,恢复其代理设置:`, proxyConfig); |
|
|
|
chrome.proxy.settings.set({ |
|
|
|
value: { |
|
|
|
mode: "fixed_servers", |
|
|
|
rules: { |
|
|
|
singleProxy: { |
|
|
|
scheme: "http", |
|
|
|
host: proxyConfig.host, |
|
|
|
port: parseInt(proxyConfig.port) |
|
|
|
}, |
|
|
|
bypassList: ["localhost", "127.0.0.1", "<local>"] |
|
|
|
} |
|
|
|
}, |
|
|
|
scope: "regular" |
|
|
|
setProxyForWindow(proxyConfig, windowId, (error) => { |
|
|
|
if (error) { |
|
|
|
console.error('恢复代理设置失败:', error); |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -483,4 +616,18 @@ chrome.windows.onFocusChanged.addListener((windowId) => { |
|
|
|
chrome.windows.onRemoved.addListener((windowId) => { |
|
|
|
console.log(`窗口 ${windowId} 被关闭,移除其代理设置`); |
|
|
|
windowProxyMap.delete(windowId); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
// 添加证书错误处理
|
|
|
|
chrome.webRequest.onErrorOccurred.addListener( |
|
|
|
function(details) { |
|
|
|
if (details.error && details.error.includes('ERR_CERT')) { |
|
|
|
console.log('忽略证书错误:', details.url); |
|
|
|
return { cancel: false }; |
|
|
|
} |
|
|
|
}, |
|
|
|
{ |
|
|
|
urls: ["<all_urls>"], |
|
|
|
types: ["main_frame", "sub_frame", "stylesheet", "script", "image", "object", "xmlhttprequest", "other"] |
|
|
|
} |
|
|
|
); |