From 19410e9f96c26488306a8e411ab548cbd120d566 Mon Sep 17 00:00:00 2001 From: go0p Date: Tue, 15 Apr 2025 17:39:33 +0800 Subject: [PATCH] fix Firefox proxy set --- src/utils/proxy.ts | 177 ++++++++++++++++++++++++++++++++------------- 1 file changed, 128 insertions(+), 49 deletions(-) diff --git a/src/utils/proxy.ts b/src/utils/proxy.ts index 072db3c..0f7225b 100644 --- a/src/utils/proxy.ts +++ b/src/utils/proxy.ts @@ -32,6 +32,111 @@ export async function getCurrentProxyMode(): Promise { } } +/** + * 检查浏览器是否支持代理API + * @returns 是否支持代理API + */ +function hasProxySupport(): boolean { + return browser.proxy !== undefined && browser.proxy.settings !== undefined; +} + +/** + * 检测当前浏览器是否为 Firefox + * @returns 是否为 Firefox 浏览器 + */ +function isFirefox(): boolean { + // 使用 WXT 提供的环境变量检测浏览器 + if (typeof import.meta.env !== 'undefined') { + // 首选方式:使用 WXT 的内置环境变量 + if (import.meta.env.FIREFOX !== undefined) { + return Boolean(import.meta.env.FIREFOX); + } + if (import.meta.env.BROWSER === 'firefox') { + return true; + } + } + return false; +} + +/** + * 修复Firefox和Chrome的代理配置差异 + * @param config 代理配置 + * @returns 浏览器特定的代理配置 + */ +function createBrowserProxyConfig(config: ProxyConfig): any { + // 不同浏览器的代理配置格式 + const firefoxBrowser = isFirefox(); + + if (config.proxyType === 'direct') { + return null; // 直接连接模式返回null,由clear方法处理 + } else if (config.proxyType === 'system') { + // 系统代理模式对两种浏览器都一样 + return { mode: 'system' }; + } else if (config.proxyType === 'fixed_servers') { + if (firefoxBrowser) { + // Firefox格式 + const proxyConfig: any = { + proxyType: 'manual' + }; + + if (config.scheme === 'http' || config.scheme === 'https') { + proxyConfig.http = `${config.scheme}://${config.host}:${config.port}`; + proxyConfig.ssl = `${config.scheme}://${config.host}:${config.port}`; + proxyConfig.httpProxyAll = true; + } else if (config.scheme === 'socks4' || config.scheme === 'socks5') { + proxyConfig.socks = `${config.host}:${config.port}`; + proxyConfig.socksVersion = config.scheme === 'socks4' ? 4 : 5; + proxyConfig.proxyDNS = true; + } + + // 设置绕过代理的列表 + if (config.bypassList && config.bypassList.length > 0) { + proxyConfig.passthrough = config.bypassList.join(', '); + } + + return proxyConfig; + } else { + // Chrome格式 + const proxyConfig: any = { + mode: 'fixed_servers', + rules: {} + }; + + // 添加代理规则 + const proxyRule = { + scheme: config.scheme, + host: config.host || '', + port: config.port || 80 + }; + + // 设置代理规则 + proxyConfig.rules = { + singleProxy: proxyRule, + bypassList: config.bypassList || ['localhost', '127.0.0.1'] + }; + + return proxyConfig; + } + } else if (config.proxyType === 'pac_script') { + if (firefoxBrowser) { + // Firefox格式 + return { + proxyType: 'autoConfig', + autoConfigUrl: config.pacScript?.url, + autoLogin: true + }; + } else { + // Chrome格式 + return { + mode: 'pac_script', + pacScript: config.pacScript + }; + } + } + + return null; +} + /** * 切换到指定的代理模式 * @param mode 代理模式(ID, direct, 或 system) @@ -39,7 +144,13 @@ export async function getCurrentProxyMode(): Promise { */ export async function switchProxyMode(mode: string): Promise { try { - // 使用自定义代理 + // 检查代理API是否可用 + if (!hasProxySupport()) { + console.error('Proxy API not supported in this browser'); + return false; + } + + // 获取对应的代理配置 const config = await getProxyConfig(mode); if (!config) { console.error(`Proxy config with ID ${mode} not found`); @@ -53,60 +164,28 @@ export async function switchProxyMode(mode: string): Promise { if (config.proxyType === 'direct') { // 直接连接模式 await browser.proxy.settings.clear({}); - } else if (config.proxyType === 'system') { - // 系统代理模式 - await browser.proxy.settings.set({ - value: { mode: 'system' }, - scope: 'regular' - }); - } else if (config.proxyType === 'fixed_servers') { - // 固定服务器代理 - const proxyConfig = { - mode: 'fixed_servers', - rules: {} - }; + } else { + // 获取浏览器特定的代理配置 + const proxyConfig = createBrowserProxyConfig(config); - // 添加代理规则 - const proxyRule = { - scheme: config.scheme, - host: config.host || '', - port: config.port || 80 - }; - - // 添加认证信息 - // if (config.username && config.password) { - // proxyRule.username = config.username; - // proxyRule.password = config.password; - // } - - // 设置代理规则 - proxyConfig.rules = { - singleProxy: proxyRule, - bypassList: config.bypassList || ['localhost', '127.0.0.1'] - }; - - // 应用代理设置 - await browser.proxy.settings.set({ - value: proxyConfig, - scope: 'regular' - }); - } else if (config.proxyType === 'pac_script') { - // PAC脚本代理 - const pacConfig = { - mode: 'pac_script', - pacScript: config.pacScript - }; - - // 应用PAC脚本设置 - await browser.proxy.settings.set({ - value: pacConfig, - scope: 'regular' - }); + if (proxyConfig !== null) { + // 应用代理设置 + await browser.proxy.settings.set({ + value: proxyConfig, + scope: 'regular' + }); + } } return true; } catch (error) { console.error(`Error switching to proxy mode ${mode}:`, error); + + // 更详细的错误信息 + if (typeof error === 'object' && error !== null) { + console.error('Error details:', JSON.stringify(error, Object.getOwnPropertyNames(error))); + } + return false; } } \ No newline at end of file