Nstproxy 现已升级为 Nstdata。了解此次变化。 周一至周五 09:00 - 18:00(UTC+08:00) 
©2026 NST LABS TECH LTD. 保留所有权利。 Node.js 代理指南用于使用 Axios 和 Fetch 进行网络爬取Lena ZhouGrowth & Integration Specialist
Node.js 使用代理进行网页抓取:Axios 和 Fetch
TL;DR
- Node.js代理用于出站抓取与JavaScript的
Proxy对象及反向代理服务器不同。
- Axios通过其请求的
proxy配置接受HTTP代理;使用明确的超时并验证返回的内容。
- Node内置的
fetch()由Undici支持,每个请求的代理路由可以使用Undici的ProxyAgent作为dispatcher。
- 为了保持粘性身份,保持一个dispatcher或代理,工作结束时关闭,仅在独立任务边界处进行轮换。
- 代理更改网络路线;它不授予权限,不解决CAPTCHA,也不会使无效的抓取器正确。
您所指的“Node.js Proxy”是什么?
对于网络抓取,Node.js代理是由HTTP客户端(如Axios或fetch)使用的出站网络中介。它不是MDN所描述的Proxy元编程对象,也不是为您的应用接受流量的反向代理。本文仅关注对公共或授权目标的出站请求。
Nstdata暴露了可以被Node HTTP客户端使用的代理网关。客户端库决定了网关的连接方式、凭据的读取方式以及连接是否被重用。现有的Axios代理指南涵盖了特定于Axios的模式;本指南直接将它们与当前Node的fetch行为进行比较。
Node在Node.js全局fetch文档中将fetch文档化为与浏览器兼容的全局对象。Node当前的企业网络指南也描述了近期版本中选择加入的环境代理支持,但特定于库的配置仍然是跨支持的运行时中最可移植的选择。
先决条件和项目设置
一个实际的Node网络抓取代理示例需要一个支持的Node运行时、一个HTTP客户端、一个授权目标以及代理凭据。示例使用ES模块并避免嵌入秘密。
mkdir node-proxy-demo
cd
node-proxy-demo
npm
init
-y
npm
install
axios undici
export PROXY_HOST="gateway.example"
export PROXY_PORT="8000"
export PROXY_USER="channel-id"
export PROXY_PASSWORD="replace-with-secret"
切勿打印完整的凭据URL。相反,记录非秘密路线ID、主机名标签、延迟和接受状态。
通过 Nstdata 连接 Axios 和 Fetch
使用托管代理会话进行可观察的、经过授权的 Node.js 数据收集。
配置 Node.js
|
|
详细教程
方法 1:配置 Axios 代理
Axios 可以在每个请求中传递代理对象,从而将凭据与目标 URL 分开。当前的 Axios 请求配置 文档描述了 proxy、auth、timeout,以及在提供自定义代理时使用 proxy: false 禁用代理处理的能力。
步骤 1:创建 Axios 客户端
import axios from "axios";
const client = axios.create({
timeout: 20_000,
proxy: {
protocol: "http",
host: process.env.PROXY_HOST,
port: Number(process.env.PROXY_PORT),
auth: {
username: process.env.PROXY_USER,
password: process.env.PROXY_PASSWORD,
},
},
headers: { "User-Agent": "authorized-monitor/1.0" },
validateStatus: () => true,
});
validateStatus: () => true 允许应用程序在一个地方检查每个 HTTP 状态,而不是将某些响应转换为运输类异常。这只有在您自己强制接受时才有用。
步骤 2:验证代理响应
const response = await client.get("https://example.com/", {
responseType: "text",
});
const accepted =
response.status === 200 &&
typeof response.data === "string" &&
response.data.includes("示例域");
if (!accepted) {
throw new Error(`未接受的响应: ${response.status}`);
}
console.log({ status: response.status, bytes: response.data.length });
一个 200 挑战页面并不是一个被接受的记录。测试一个稳定的字段、选择器、模式或属于授权目标的内容标记。一旦运输可靠,JavaScript 网络爬虫指南 会添加解析模式。
方法 2:使用 Node fetch 的代理
Node fetch 可以通过作为 dispatcher 提供的 Undici ProxyAgent 路由请求。官方的 Undici ProxyAgent 文档 显示了代理 URI、dispatcher 选项和显式的 close() 生命周期。
步骤 1:安全地构建凭据 URL
import { ProxyAgent } from "undici";
const user = encodeURIComponent(process.env.PROXY_USER);
const password = encodeURIComponent(process.env.PROXY_PASSWORD);
const proxyUrl = `http://${user}:${password}@${process.env.PROXY_HOST}:${process.env.PROXY_PORT}`;
const dispatcher = new ProxyAgent(proxyUrl);
对凭据组件进行编码可以防止 @、: 或 / 改变代理 URL 结构。保持 URL 限定在进程内并避免错误。
步骤 2:获取、验证和关闭
try {
const response = await fetch("https://example.com/", {
dispatcher,
signal: AbortSignal.timeout(20_000),
headers: { "user-agent": "authorized-monitor/1.0" },
});
const html = await response.text();
if (response.status !== 200 || !html.includes("示例域")) {
throw new Error(`未接受的响应: ${response.status}`);
}
console.log({ status: response.status, bytes: html.length });
} finally {
await dispatcher.close();
}
关闭调度程序释放了池化的套接字,当短期作业结束时。服务器进程可以重用调度程序以其预期身份,并在优雅关闭期间关闭它。
按作业轮换代理,而不是按代码行
Node 代理轮换是一项编排决策:为一个独立的作业选择一个路由,保留它以进行相关请求,然后关闭其网络资源。
import { ProxyAgent } from "undici";
const routes = [
"http://127.0.0.1:9001",
"http://127.0.0.1:9002",
];
async function fetchAccepted(url, proxyUrl) {
const dispatcher = new ProxyAgent(proxyUrl);
try {
const response = await fetch(url, {
dispatcher,
signal: AbortSignal.timeout(15_000),
});
const body = await response.text();
if (response.status !== 200 || !body.includes("示例域")) {
return { accepted: false, status: response.status };
}
return { accepted: true, status: response.status, bytes: body.length };
} finally {
await dispatcher.close();
}
}
for (const [index, url] of ["https://example.com/", "https://example.org/"].entries()) {
const result = await fetchAccepted(url, routes[index % routes.length]);
console.log({ job: index, ...result });
}
循环是有限的,并且不会重试拒绝。生产池应存储连续失败、冷却时间、最近的延迟和最后接受的时间戳。重试需要指数回退加抖动,并且只有幂等请求才应自动重放。批处理抓取指南 解释了为什么在 URL 集增长时,检查点和接受输出的会计很重要。
Nstdata Residential Prime Proxies 适合需要 HTTP/HTTPS 网关以及旋转或粘性会话控制的授权节点作业。该产品可以集中路由选择,而 Axios 或 Undici 则负责超时、套接字生命周期和语义验证。当前的产品材料描述了 HTTP、HTTPS 和 SOCKS5 协议及会话持久性选项。选择旋转用于独立的 URL,选择粘性会话用于需要保持连续性的分页或无登录旅程;代理访问绝不覆盖目标策略。
- Residential Prime 代理会话: 将一个提供者会话 ID 映射到一个逻辑节点作业,并仅在干净边界时续订。
- 客户端兼容性: 使用 Axios 的
proxy 对象或 Undici 的 dispatcher,而不是假设每个 Node 包以相同的方式读取环境变量。
- 有效接受: 追踪有效记录、挑战页、传输失败和延迟,确保路由质量可观察。
Axios 与 Fetch 代理决策表
Axios 和 fetch 都可以使用经过身份验证的 HTTP 代理,但它们的配置界面和响应默认值有所不同。
| 决策 | Axios | Node fetch + Undici |
|---|
| 代理附加 | 请求 proxy 对象 | ProxyAgent 調度器 |
| 非 2xx 默认 | Axios 默认拒绝 | fetch 解析;检查 ok 或状态 |
| 超时 | Axios timeout | AbortSignal.timeout() |
| 套接字生命周期 | 由 Axios/代理管理 | 明确重用和关闭调度器 |
| 凭证 | proxy.auth 对象 | 编码代理 URI 或文档化的令牌选项 |
如果项目已经使用 Axios 的拦截器和错误模型,则选择 Axios。在减少包装依赖和明确调度器控制时选择本机 fetch 和 Undici。除非客户端配置为 proxy: false,否则不要将 Axios 的内置代理字段与自定义隧道代理混合;重复配置会导致混淆路由。
排查 Node 代理错误
Node 代理失败需要分别诊断传输、身份验证、超时和内容。
| 症状 | 检查 |
|---|
ECONNREFUSED | 代理主机、端口、监听器、防火墙 |
ETIMEDOUT 或中止 | 连接/读取预算、目标延迟、代理健康 |
HTTP 407 | 代理凭证或允许列表;不要盲目重试 |
HTTP 403 或挑战 HTML | 授权和目标政策;停止,而不是激进地轮转 |
| Axios 忽略代理 | 确保自定义代理负责路由时使用 proxy: false |
| 进程不退出 | 关闭 Undici 调度器和其他打开的句柄 |
结论
一个可靠的 Node.js 网页抓取代理设置开始于选择正确的客户端边界:一个 Axios 代理对象或一个 Undici 调度器。在提高吞吐量之前,添加安全配置、超时、语义响应检查、有限轮换和资源清理。Nstdata 可以提供托管会话,而您的应用程序仍然负责授权和接受的数据。
常见问题解答
Node fetch 可以使用作为请求 dispatcher 传递的 Undici ProxyAgent。环境代理行为因 Node 版本和自选设置而异,因此明确的库配置在混合部署中更清晰。
在 Axios 请求配置中设置 proxy.auth.username 和 proxy.auth.password。从秘密存储或环境变量中读取这两个值,绝不要记录生成的配置对象。
Q: JavaScript Proxy 与 HTTP 代理有关吗?
不,JavaScript Proxy 拦截语言运行时内部的对象操作。HTTP 代理是 Axios、fetch、浏览器或其他客户端使用的网络中介。
Q: 我需要为每个请求创建一个新的 ProxyAgent 吗?
对共享稳定身份的请求重用一个 ProxyAgent,然后在工作或进程结束时关闭它。当路由或会话身份故意更改时,创建一个新的代理。
Q: 为什么 Axios 能工作而 fetch 在同一个代理下失败?
Axios 和 fetch 使用不同的代理配置表面。确认 Axios 使用 proxy,fetch 使用 Undici dispatcher,凭据编码正确,并且两个客户端都应用相同的超时和接受检查。
不,代理只改变网络路线。它不提供访问权限,不在 HTTP 仅限客户端执行 JavaScript,不解决 CAPTCHA,也不替代对网站条款和适用法律的遵守。
Sep. 15th 2026
立即访问住宅、数据中心、IPv6 与 ISP 高质量代理池。