在 Node 的 Undici 中使用代理 IP
为单次 fetch 请求指定 Undici ProxyAgent,让其连接池与无关的 Node 流量分开。
Undici 通过分发器路由请求。为所选 HTTP 代理创建 ProxyAgent,并在 fetch 调用中传入,而不是更改整个进程的全局分发器。
npm install [email protected]
import { fetch, ProxyAgent } from 'undici';
const dispatcher = new ProxyAgent('http://203.0.113.10:8080');
try {
const response = await fetch('https://example.com/', {
dispatcher,
signal: AbortSignal.timeout(15000),
});
console.log(response.status);
console.log(await response.text());
} finally {
await dispatcher.close();
}
将程序保存为 .mjs 文件,或使用 ES 模块项目。把文档示例 IP 替换为来自HTTP 代理列表的 HTTP 代理。导入明确使用 Undici 自身的 fetch 实现,因此 dispatcher 选项属于示例所用的客户端。
先检查 Node 兼容性,再判断是否是 IP 的问题
Undici 支持哪些 Node 版本取决于软件包版本。本例使用 Undici 8.12.3,要求 Node 22.19.0 或更新版本。模块加载或引擎版本错误发生在请求到达代理之前。应查看已安装软件包的引擎要求,不要假定所有 Node 版本都能运行最新 Undici。
一个 agent 可以处理多次请求
这个短程序结束时会关闭分发器。如果运行中的应用通过相同端点发送多次请求,应在该工作负载期间保留 agent,并在工作结束时关闭。为每个 URL 分别创建再关闭 agent,会妨碍有效的连接复用。
只有明确需要更大范围的变更时,才适合使用全局分发器。显式传入分发器,更容易在不改变其他组件出站请求的情况下测试代理 IP。
查看响应及失败阶段
fetch 不会把所有 HTTP 错误状态都当作 Promise 拒绝。403 或 429 可能是经代理传回的网站真实响应。连接或隧道错误则可能在响应对象产生前就使请求被拒绝。应分别读取状态和调用抛出的错误。
如果需要认证,Undici 的 ProxyAgent 提供构造函数层面的认证选项。不要把代理授权头加入网站请求头;agent 处理的是另一段连接。