Electron 应用如何获取系统代理配置

January 19, 2022

macOS System Proxy

操作系统默认都有上图这种系统级别的代理配置,但是像 Electron 应用,主进程的网络请求默认并不会走这个系统代理,这个默认行为很容易给用户来带不便从而惹恼用户。如果开发者要让主进程里的网络请求走系统代理,需要用一些技巧。

读取系统代理配置

找到正确读取系统代理的方法并不是一帆风顺的,着实让我花了一点时间,也踩了不少可坑,最终我测试可行的方案如下,这个方案同时支持 macOS 和 windows

以下代码需要放在主线程执行

const mainWindow = new BrowserWindow({
  show: false,
  width: 1024,
  height: 768,
})

// 读取浏览器的 session
const session = mainWindow.webContents.session

// 下面的代码会尝试解析代理配置,如果用户配置了系统代理,
// 并且代理规则没有排除 www.google.com,那我们就可以读取到代理信息
session.resolveProxy('https://www.google.com').then((proxyUrl) => {
  // DIRECT 表示没有配置代理
  if (proxyUrl !== 'DIRECT') {
    // proxyUrl 是这种格式: 'PROXY 127.0.0.1:6152'
    const hostAndPort = proxyUrl.split(' ')[1]
    const [proxyHost, proxyPort] = hostAndPort.split(':')

    // 到这里就拿到代理服务器的信息了,这里我用 https-proxy-agent 这个 npm 包让 Axios 的默认请求强制走系统代理
    // @ts-ignore
    const agent = new HttpsProxyAgent({
      host: proxyHost,
      port: proxyPort,
    })
    Axios.defaults.httpsAgent = agent
  }
})

本文代码在最新的 Electron 16 版本测试通过

优化空间

上面的代码只是拿到了系统代理配置,但是在用户手动改了系统代理配置的情况下,我们程序里的配置信息还是旧的,所以想要极致的用户体验,我们是需要想办法监听这个变动的。不然网络请求就会出错了。

如果你没有特殊需求,可以将网络请求放在 renderer 进程中用 xhr 或者 fetch 执行,这样网络代理会由 chromium 自动处理,开发者不需要关心如何获取和监测系统代理变化,这些复杂的部分都由 chromium 在底层帮你处理好了,就像浏览器一样。

引用

本文原载于:baiyun.me

原文链接:https://baiyun.me/how-electron-app-get-the-system-proxy-config

如果你喜欢我的内容,请考虑请我喝杯啤酒🍺吧,非常感谢🥰 。

If you like my contents, please support me via BuyMeCoffee, Thanks a lot.