背景
因为 wadesk 开发了本地 http 服务,http 本地服务是运行在 electron-main 的纯 node 环境中的,这个之前探讨了 node 下怎么使用 fetch 时就提到了一个 https-proxy-agent 库,这次使用 axios,发现 axios 自带 proxy 配置项,就没有多想,造成了 4 个小时的时间浪费,此次排查应该作为一个反思例子对待。
陷入误区的几个点
-
初始给同事 node-fetch 如何使用系统Proxy的函数,同事拷贝时遗漏掉了 protocol,协议没有,这个测试好几个回合,在此之前的操作误以为 useProxy 被执行了,实际打印日志时发现并没有得到执行,原因是 useProxy 的设置位置应该在 response 的 catch(error) 回调中设置。这个过程大概耗费了 2 个多小时。
-
之后就是正确设置了 axios.config.proxy 选项后,发现远程请求成功了,但是一直不返回数据,通过设置监控日志也没捕获到问题,最后更换我们的XXX发现是 OK 的,同时在用户的渲染进程 console 中执行也是 OK 的,这就陷入了不可解决的地步。
-
初步揣测可能是主进程的请求就没发出去(结果证明是错误的)
-
-
后经过晚上我再次推演,推测请求应该是发送出去了,否则就会报网络错误,返回数据也返回了,唯一可能发生问题的点有可能是 https ssl 返回数据的解密过程出了问题,导致解密失败后返回空字符串。
-
在这个思路下,去询问 chatgpt,httpsAgent 可以更好的处理 TTL 加解密过程,通过查看 axios node 源码发现,config.proxy 的代码很简单,只是配置了一个标签,并未实质参与 SSL 这种加解密过程
-
这不是核心问题,核心是客户的网络是企业配置的可以监控 https 流量内容,比如访问 QQ,微信等,这才是我们的XXX和用户的企业XXX的区别点,我们使用的商业化XXX主要目的是转发,没有监控,所以没有中间加解密,你们可以理解为 mitmproxy 模式可以修改请求和响应的概念
-
这种监控存在下,响应数据的解密过程就可能出现异常,二次解密时肯定是错误
-
-
询问 GPT 给出的结论是 https-proxy-agent 支持这种二次加解密过程,那大概率问题就出在这里了,第二天调整为 config.httpsAgent = https-proxy-agent 模式后,果然返回数据正常了
-
mac 系统上的 socks-proxy-agent
windows 只有 http 类型的协议,在 mac 系统上还支持了 socks 协议
const axios = require('axios');
const SocksProxyAgent = require('socks-proxy-agent');
const socksProxy = 'socks5://127.0.0.1:1080';
// 创建 socks agent
const agent = new SocksProxyAgent(socksProxy);
axios.get('https://example.com', {
httpsAgent: agent
})
.then(response => {
console.log('Response:', response.data);
})
.catch(error => {
console.error('Error:', error.message);
});