[教程] Electron.js 怎么做代理
BrowserWindow.webContents.session.setProxy
这篇文章对谁有用?
- Electron.js 开发者
这篇文章讲什么?
Electron.js 如何实现代理功能。
比如:
界面解释
- 用户可以输入代理地址到 HTTP_PROXY。
- 右侧有个开关,"已开启"|"已关闭"
- 代理设置完了,下方可以"测试代理连通性"
背景信息
我在做 Electron 桌面应用,需要和谷歌 API 交互。翻墙是个问题。
希望 Electron 能直接用我本地的代理 (http://127.0.0.1:1087)
注:本文写于2019年12月27号。
我用的 Electron.js 版本是 6.1.5
我知道最新版是 7,但是安装一直碰到问题,所以没用 7
本文结构
- 先讲结论
- 给代码
- 最后讲过程,可我犯了什么错,也可以跳过不看
先讲结论
用这个:
BrowserWindow.webContents.session.setProxy
文档: https://electronjs.org/docs/api/session
给代码
index.js
(Main process) 代码:
const {
app,
BrowserWindow,
ipcMain,
Menu
} = require('electron')
let win
function createWindow() {
win = new BrowserWindow({
width: 820,
height: 840,
titleBarStyle: 'hidden',
frame: false,
webPreferences: {
nodeIntegration: true,
}
})
}
这一段只是前置条件,帮助理解后面的代码。
只要知道这里有个变量叫 win
, 类型是 BrowserWindow
就行了
重点来了,index.js
文件的下半部分
// 设置代理
ipcMain.on('set_proxy', (event, arg) => {
console.log(arg);
var { http_proxy } = arg
win.webContents.session.setProxy({
proxyRules: http_proxy
}, function () {
console.log('代理设置完毕')
});
})
// 去掉代理
ipcMain.on('remove_proxy', (event, arg) => {
win.webContents.session.setProxy({});
})
可以看到这里是监听 ipc,如果收到对应名字的事件就运行代码
如果想了解更多 ipcMain
和 ipcRender
,以下是文档:
https://electronjs.org/docs/api/ipc-main
https://electronjs.org/docs/api/ipc-renderer
怎么使用?
在 Render Process 里:
// 设置代理
set_proxy() {
window.ipcRenderer.send("set_proxy", {
http_proxy: this.setting_http_proxy
});
},
// 取消代理
remove_proxy() {
window.ipcRenderer.send("remove_proxy");
},
因为我用的是 Vue.js
这2个函数我是写在 methods:
里
<template>
</template>
<script>
export default {
methods: {
// 这里
}
}
</script>
<style>
</style>
还有一件事
前面代码里 window.ipcRenderer
可能看起来很奇怪。
干嘛要带个 window. 在前面?
这是因为我另外有一段:
const {
ipcRenderer,
} = window.require("electron")
window.ipcRenderer = ipcRenderer;
这就保存到了 window 变量里,render process 里的代码可以很方便的拿到。
因为 webpack 和 node 有干扰(具体原理我也不清楚,没关心)
所以要用 window.require
代码部分到此结束。
以下进入本文第三部分,也是最后一部分:犯过的错
犯过的错
错误1:直接用 axios/request 的 proxy 配置
错误2:环境变量
错误1:直接用 axios/request 的 proxy 配置
一开始我的思路还没转过来,忘记这是桌面应用了。
就去看 Node.js 网络库怎么配置代理。
测试了 axios, requests, superagent, 原生 fetch 和 got.
好像还测了几个其他的名气比较小的库,无一成功。
一开始我以为是自己哪里弄错了。不太理解。后来才想起来一切请求最终都是通过 Chrome 发出去的。这是个桌面应用,我搞错方向了。
错误2:环境变量
我以为设置环境变量 HTTP_PROXY 和 HTTPS_PROXY,
axios, requests 等等库发出去的请求就会尊重这个环境变量。我错了。
简而言之,在这2个错误上浪费了2天时间。
换了个思路,看 Electron 本身这个请求是怎么出去的,应该是在外面这一层,
然后找到了 setProxy,一试,可以。这才解决了问题。
补几个有用的链接:
https://github.com/electron/electron/issues/21050
全文完
感谢阅读