惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Last Watchdog
The Last Watchdog
S
Securelist
T
Threat Research - Cisco Blogs
Forbes - Security
Forbes - Security
AI
AI
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Attack and Defense Labs
Attack and Defense Labs
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Know Your Adversary
Know Your Adversary
P
Privacy International News Feed
W
WeLiveSecurity
P
Palo Alto Networks Blog
O
OpenAI News
V2EX - 技术
V2EX - 技术
H
Heimdal Security Blog
L
Lohrmann on Cybersecurity
NISL@THU
NISL@THU
T
Tor Project blog
T
Threatpost
G
GRAHAM CLULEY
T
The Exploit Database - CXSecurity.com
云风的 BLOG
云风的 BLOG
人人都是产品经理
人人都是产品经理
A
Arctic Wolf
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Latest news
Latest news
Application and Cybersecurity Blog
Application and Cybersecurity Blog
T
Tenable Blog
量子位
L
LINUX DO - 最新话题
Webroot Blog
Webroot Blog
F
Fortinet All Blogs
C
CERT Recently Published Vulnerability Notes
Hacker News: Ask HN
Hacker News: Ask HN
U
Unit 42
T
Tailwind CSS Blog
WordPress大学
WordPress大学
N
News | PayPal Newsroom
C
CXSECURITY Database RSS Feed - CXSecurity.com
N
Netflix TechBlog - Medium
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Stack Overflow Blog
Stack Overflow Blog
Cloudbric
Cloudbric
C
Check Point Blog
V
Visual Studio Blog
The GitHub Blog
The GitHub Blog
The Hacker News
The Hacker News
B
Blog

BAIYUN'S BLOG

AI Coding 从小工到专家 - BAI YUN 电信 IPTV 内网融合教程:在局域网任意设备观看 IPTV - BAI YUN 美国住宅 IP 提供商体验对比 - BAI YUN Node.js 程序以 Keyless 模式从 1Password 读取密钥 - BAI YUN 高效优雅的观影指南 - BAI YUN 基于 Surge 的 DNS 优化指南 - BAI YUN RIME 鼠须管输入法简明使用教程 - BAI YUN 自动给不同 Git 项目设置不同的用户名邮箱 - BAI YUN Web3 新手如何选择加密货币钱包 - BAI YUN Web3 到底是什么? - BAI YUN 谨慎开启 Safari 的阻止跨站跟踪功能 - BAI YUN iOS Surge 开启后无法使用部分国产 APP 或网络出错的解决办法 - BAI YUN 屏蔽 Telegram 垃圾私信的有效办法 - BAI YUN 每个人都应该读一遍《1984》和《动物庄园》 - BAI YUN iOS 给常见机构号码增加联系人头像 - BAI YUN 在国内如何购买比特币和投资加密货币 - BAI YUN WEB 性能优化:如何让你的网站页面秒开(方法论) - BAI YUN 加密货币投资这件事 - BAI YUN 国内手机号注册推特教程 - BAI YUN 国内注册币安账号并通过 KYC 教程 - BAI YUN 使用一套助记词创建多个以太坊钱包账户 - BAI YUN Apple Watch 的几个用途 - BAI YUN 钱包安全指南:如何保护你的 NFT 和加密资产不被盗 - BAI YUN 我在 macOS 上高频使用的应用 - BAI YUN Web3 时代:如何使用 MetaMask 钱包实现一键登录 - BAI YUN 2022 年了 Safari 无法渲染渐变文字的 BUG 依旧存在 - BAI YUN 境外手机卡:澳门电信大湾区预付卡使用体验 - BAI YUN 解决 iCloud Drive 上传文件卡住的问题 - BAI YUN 解决 iOS 上 Google 账号登录会卡在加载状态的问题 - BAI YUN 记录 Github Copilot 惊讶到我的时刻 - BAI YUN 解决 Xbox 在国内下载速度慢 - BAI YUN 开始使用 IndexNow - BAI YUN Surge iOS 和 AmpliFi 的兼容性问题 - BAI YUN 自建图床指南 - BAI YUN 使用 TypeScript 提升可维护性 - BAI YUN 在 JavaScript 应用中正确的实现时区切换 - BAI YUN 从 Loading 动画出发改进 React 应用的用户体验 - BAI YUN Node.js Tips - BAI YUN 使用 Dart Sass 代替 Node Sass - BAI YUN WSL 踩的坑和解决方法 - BAI YUN NPM & Yarn Tips - BAI YUN Git Tips - BAI YUN macOS 命令行 Tips - BAI YUN JavaScript 防劫持 - BAI YUN Dota2 - BAI YUN macOS 好用的系统维护工具 - BAI YUN 在 Linux 服务器上使用 Puppeteer 生成 PDF - BAI YUN The Golden Circle 黄金圆环法则 - BAI YUN CSS 写法进化史 - BAI YUN 一个 Web 开发者的 Windows10 开发环境设置心得 - BAI YUN Chrome DevTools Tips - BAI YUN React 设计模式和思想 - BAI YUN Linux & Unix 命令行环境的一些 Tips - BAI YUN 从传统 MVC 到同构:Web 发展历程 - BAI YUN Webpack 动态导入 - BAI YUN JavaScript 中的异步 - BAI YUN 关于我的博客 - BAI YUN
Electron 应用如何获取系统代理配置 - BAI YUN
baiyun · 2022-01-19 · via BAIYUN'S BLOG

macOS System Proxy

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

读取系统代理配置

方法一:session.resolveProxy

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

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

import HttpsProxyAgent from 'https-proxy-agent'

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 版本测试通过

方法二:系统命令

在 Electron 应用的主进程中,通过 Node.js 的 child_process 模块执行系统命令获取系统代理信息。不同操作系统的获取方式不同,并且随着系统升级可能出现命令不可用或者输出格式变化等不稳定情况。

在 macOS 系统上:

const { execSync } = require('child_process')

function getMacWebProxy() {
  // 这种方法需要考虑到用户使用不同网卡的情况,Wi-Fi 是网络设备名称,对于使用有线网卡的用户,可能需要替换成 Ethernet 等适当的名称
  const cmd = 'networksetup -getwebproxy "Wi-Fi"'
  const output = execSync(cmd).toString()
  const result = output.match(/(?:Enabled:\s)(\w+)\n(?:Server:\s)([^\n]+)\n(?:Port:\s)(\d+)/)

  if (result) {
    const [_, enabled, server, port] = result
    if (enabled === 'Yes') {
      return `http://${server}:${port}`
    }
  }

  return null
}

const proxyConfig = parseProxyConfig(rawProxyInfo)
console.log(proxyConfig) // 输出代理配置字符串,如 "http://127.0.0.1:6152"

在 Windows 系统上(未验证):

const { execSync } = require('child_process')
const proxyConfig = execSync(
  'reg query "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" /v ProxyServer',
)
  .toString()
  .split('\r\n')
  .filter((line) => line.trim())
  .pop()
  .split('    ')
  .pop()

console.log(proxyConfig) // 输出代理配置字符串,如 "http://proxy.example.com:8080"

优化空间

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

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

引用

本文原载于:baiyun.me

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