返回 AI 资讯
技术社区SegmentFault 技术问答

Node.js 内置 fetch 无法走 SOCKS5 代理,只能换掉整个 HTTP 栈吗?

项目里要访问一个只能通过 SOCKS5 出去的接口,Node 端用的是 18+ 自带的全局 fetch (undici 实现)。卡在代理上:undici 提供的是 ProxyAgent ,只认 HTTP/HTTPS 代理, 没有 SOCKS5 支持 。 试了几种把全局出口改成 SOCKS5 的写法,都没能让内置 fetch 走代理: // 1) 直接把 ProxyAgent 指到 socks5 import { setGlobalDispatcher, ProxyAgent } from 'undici'; se…

内容摘要

项目里要访问一个只能通过 SOCKS5 出去的接口,Node 端用的是 18+ 自带的全局 fetch (undici 实现)。卡在代理上:undici 提供的是 ProxyAgent ,只认 HTTP/HTTPS 代理, 没有 SOCKS5 支持 。 试了几种把全局出口改成 SOCKS5 的写法,都没能让内置 fetch 走代理: // 1) 直接把 ProxyAgent 指到 socks5 import { setGlobalDispatcher, ProxyAgent } from 'undici'; setGlobalDispatcher(new ProxyAgent('socks5://127.0.0.1:1080')); // → 协议不被识别 // 2) 环境变量 // HTTPS_PROXY=socks5://127.0.0.1:1080 // 3) 老的 agent 方案 import { SocksProxyAgent } from 'socks-proxy-agent'; const agent = new SocksProxyAgent('socks5://127.0.0.1:1080'); // 这个 agent 只认 https.request,fetch 用的是全局 dispatcher,两者不是一套 global-agent 的 bootstrap() 也一样:它改的是 http / https 模块的 agent,覆盖不到 undici。 想确认的是: 有没有办法让内置 fetch 走 SOCKS5,而不用把业务代码整体换成 axios + agent,或者退回 node-fetch ? 如果结论是「必须自己实现一个 Dispatcher」,那想了解需要覆盖哪些方法( dispatch 、 connect ?),以及有没有现成的社区实现可以复用,而不是自己糊一个。 做过的尝试 setGlobalDispatcher(new ProxyAgent('socks5://127.0.0.1:1080')) —— undici 直接拒绝这个协议, ProxyAgent 只实现了 HTTP CONNECT 隧道,不解析 socks5。 HTTPS_PROXY / HTTP_PROXY 环境变量设成 socks5://… —— undici 会读环境变量生成 dispatcher,但同样只认 http/https 协议。 global-agent 的 bootstrap() —— 它替换的是 http.globalAgent / https.globalAgent ,而 fetch 走的是 undici 的全局 dispatcher,两者完全不是一条路。 socks-proxy-agent 创建 agent 后传给 https.request —— 这条是通的,但换到 fetch 上没有任何入口可以注入 agent( fetch 的第二个参数只认 dispatcher ,不认 agent )。 试过 undici.Agent 的 connect 选项自定义 socket,但对「先建立隧道再发请求」这一步没有现成的钩子。 期望获得的结果 一个 业务代码不用改 的方案:仍然 await fetch(url) ,只是底层出口换成 SOCKS5; 如果确实做不到,希望明确「必须自己写 Dispatcher」这个结论,并指明实现它需要覆盖哪些接口、有没有已经维护得不错的第三方实现可以直接用。 实际得到的结果 现在只能把用到这个接口的那部分代码改成 axios + socks-proxy-agent ,同一个项目里出现两套 HTTP 栈,错误处理和超时语义都要重写一遍。想先确认这是不是唯一的路。

资讯来源

SegmentFault

原文链接

打开原文