Node.js fetch怎么走代理?Undici Dispatcher与环境变量排查

内置fetch、Undici和旧http.Agent不是同一套接口,先确认版本和Dispatcher
发布于
10

Node.js脚本里设置了 HTTP_PROXY,浏览器也能走代理,但 fetch() 仍然直连,这并不罕见。现代Node.js内置fetch与Undici生态紧密相关,其代理配置、全局Dispatcher和环境变量行为要按当前Node与Undici版本确认,不能直接套用旧版 http.Agent 示例。

一、先确认运行环境

  • Node.js具体版本;
  • 使用内置fetch、undici包、axios还是其他库;
  • 代码运行在本机、容器、Serverless还是CI;
  • 是否存在HTTP_PROXY、HTTPS_PROXY、NO_PROXY或平台注入;
  • 是否需要HTTP代理、HTTPS代理或SOCKS5;
  • 是否使用企业TLS检查和自定义CA。

不同库不必共享同一Agent接口。

二、Dispatcher是什么

Undici使用Dispatcher抽象连接调度。代理场景通常通过当前版本支持的ProxyAgent或环境代理Agent创建Dispatcher,再传给请求或设置受控的全局Dispatcher。

具体构造函数和环境代理能力可能随版本变化,必须参考当前官方文档。不要复制未标注Node版本的代码。

三、局部Dispatcher优于全局修改

如果只有一个外部API需要代理,把Dispatcher传给该客户端更可控;全局设置会影响同一进程内所有使用Undici的请求,可能让健康检查、内部服务和元数据请求改变路径。

封装一个外部API客户端,明确代理、超时和关闭生命周期,比在应用入口全局修改更容易测试和回滚。

四、环境变量为什么可能不生效

环境变量是约定,不是所有Node HTTP库自动遵守的规则。要确认:

  • 当前Node/Undici是否提供环境代理Agent;
  • 是否显式启用;
  • 大小写变量和优先级;
  • NO_PROXY语法与端口匹配;
  • 应用启动后才修改变量是否已错过读取时机。

五、SOCKS5不能直接当HTTP代理

HTTP ProxyAgent通常按HTTP CONNECT等方式工作,SOCKS5是不同协议。若业务必须使用SOCKS5,应选择明确支持当前Node版本和fetch接口的可信实现,并验证DNS、IPv6和认证。

协议区别可参考SOCKS5与HTTP代理选型

六、连接池与进程退出

Dispatcher通常维护连接池。频繁为每个请求创建Agent会增加握手和资源消耗;长期进程应复用并在关闭时正确释放。测试脚本若不关闭连接,进程可能继续等待。

切换代理或凭据时创建新Dispatcher,停止给旧池分配请求,待在途请求完成后关闭。

七、超时和AbortSignal

fetch需要明确超时和取消策略。可以使用当前Node支持的AbortSignal工具或自建AbortController,但要区分总截止时间与连接/响应阶段。取消后确认响应体和连接是否正确清理。

不要让任务无限等待代理连接。

八、TLS和企业CA

HTTPS经代理出现证书错误时,不应设置 NODE_TLS_REJECT_UNAUTHORIZED=0。该变量会削弱整个进程的TLS验证,风险远超单个请求。

应确认目标域名、SNI、证书链、企业CA和当前Agent配置。参考代理TLS与证书排查

九、NO_PROXY要保护哪些地址

内部API、数据库网关、localhost、容器服务名、云元数据和必须直连的管理端点需要按实际架构评估。环境Agent是否支持域名后缀、端口、IPv6和CIDR,应通过当前实现测试。

十、分层验证

  1. 用内置fetch访问自有外部健康端点;
  2. 在代理日志确认节点和来源;
  3. 访问内部测试端点,确认NO_PROXY直连;
  4. 验证407、连接超时和TLS失败;
  5. 核对IPv4、IPv6和DNS路径;
  6. 关闭Dispatcher,确认进程退出和资源释放。

十一、常见故障

现象 方向
HTTP_PROXY有值但fetch直连 当前fetch未自动读取或未启用环境Agent
axios能用,fetch不能用 两者Agent和代理配置接口不同
内部地址也走代理 全局Dispatcher或NO_PROXY问题
切换后仍旧出口 Dispatcher连接池复用
脚本不退出 连接池或响应体未关闭

十二、日志安全

不要记录Dispatcher内部完整URL、代理userinfo、Cookie或Authorization。使用节点ID、配置版本、请求ID和错误阶段追踪。

Node.js代理稳定性的关键,是把版本、客户端、Dispatcher和生命周期写清楚,而不是只在进程环境里放一个变量后期待所有库自动响应。

常见问题(FAQ)

设置HTTP_PROXY后Node.js fetch一定会走代理吗?
不能假定。要确认当前Node与Undici版本是否支持并启用了环境代理Agent,或显式提供Dispatcher。
可以把旧版http.Agent直接传给fetch吗?
不能假定兼容。内置fetch基于Undici调度抽象,应按当前版本文档使用Dispatcher或支持的Agent。
为什么切换代理后fetch仍使用旧出口?
Dispatcher连接池可能复用旧连接,应创建新Dispatcher并排空、关闭旧池。
证书错误能设置NODE_TLS_REJECT_UNAUTHORIZED=0吗?
不应。它会削弱整个进程TLS验证,应修复域名、SNI、证书链、企业CA或Agent配置。

本文由作者原创/授权发布于极跃圈(jiyueip.com)未经许可,禁止转载。题图来自Unsplash,基于CC0协议。

声明:极跃圈(JIYUEIP.com)内网友所发表的所有内容及言论仅代表其本人,并不反映任何极跃圈(JIYUEIP.com)之意见及观点。

0 讨论
热门最新
总结
暂无总结
0 / 600