Node.js HTTP 客户端隧道代理:axios / got / http 三种实现对比
Node.js 三种主流 HTTP 客户端(axios + https-proxy-agent、got、原生 http)对接亿牛云爬虫代理的四种场景实现。
亿牛云技术团队2026年6月1日1 分钟阅读
Node.js 生态的代理方案
Node.js 的 HTTP 客户端通过 http-proxy-agent / https-proxy-agent 包实现代理支持。其中 https-proxy-agent 支持在 HTTPS CONNECT 阶段传入自定义头,实现 Proxy-Tunnel。
环境准备
export PROXY_HOST=t.16yun.cn
export PROXY_PORT=31111
export PROXY_USERNAME=your-username
export PROXY_PASSWORD=your-password
export PROXY_TUNNEL=nodejs-demo-12345
方案一:axios + https-proxy-agent
https-proxy-agent 的第二个参数 options.headers 可以在 CONNECT 阶段注入自定义头:
const axios = require('axios');
const { HttpProxyAgent } = require('http-proxy-agent');
const { HttpsProxyAgent } = require('https-proxy-agent');
const host = process.env.PROXY_HOST || 't.16yun.cn';
const port = process.env.PROXY_PORT || '31111';
const user = process.env.PROXY_USERNAME || 'user';
const pass = process.env.PROXY_PASSWORD || 'password';
const proxyUrl = `http://${user}:${pass}@${host}:${port}`;
// 场景 C-HTTPS:Proxy-Tunnel 固定 IP
const tunnelVal = process.env.PROXY_TUNNEL || 'axios-demo';
const httpsAgent = new HttpsProxyAgent(proxyUrl, {
headers: { 'Proxy-Tunnel': tunnelVal }, // CONNECT 阶段发送
});
async function main() {
for (let i = 1; i <= 3; i++) {
const resp = await axios.get('https://httpbin.org/ip', {
httpsAgent,
timeout: 15000,
});
console.log(`请求 ${i}: ${resp.data.origin}`);
}
}
main();
四种场景在 axios 中的实现
// 场景 A:强制切换——每次创建新 Agent
for (let i = 1; i <= 3; i++) {
const agent = new HttpsProxyAgent(proxyUrl);
const resp = await axios.get('https://httpbin.org/ip', {
httpsAgent: agent,
headers: { 'Connection': 'close', 'Proxy-Connection': 'close' },
});
}
// 场景 B:Keep-Alive——复用 Agent
const agentKeep = new HttpsProxyAgent(proxyUrl);
for (let i = 1; i <= 3; i++) {
const resp = await axios.get('https://httpbin.org/ip', {
httpsAgent: agentKeep,
headers: { 'Connection': 'keep-alive', 'Proxy-Connection': 'keep-alive' },
});
}
// 场景 C-HTTP:Proxy-Tunnel——请求头添加
const resp = await axios.get('http://httpbin.org/ip', {
httpAgent: new HttpProxyAgent(proxyUrl),
headers: { 'Proxy-Tunnel': tunnelVal },
});
// 场景 C-HTTPS:Proxy-Tunnel——Agent options 注入
const tunnelAgent = new HttpsProxyAgent(proxyUrl, {
headers: { 'Proxy-Tunnel': tunnelVal },
});
const resp = await axios.get('https://httpbin.org/ip', { httpsAgent: tunnelAgent });
方案二:got
got 通过 agent 参数支持代理:
const got = require('got');
const { HttpsProxyAgent } = require('https-proxy-agent');
const tunnelVal = process.env.PROXY_TUNNEL || 'got-demo';
const agent = {
https: new HttpsProxyAgent(proxyUrl, {
headers: { 'Proxy-Tunnel': tunnelVal },
}),
};
(async () => {
for (let i = 1; i <= 3; i++) {
const resp = await got('https://httpbin.org/ip', { agent });
console.log(`请求 ${i}: ${JSON.parse(resp.body).origin}`);
}
})();
方案三:原生 http 模块
Node.js 原生 http.request 直接发送 Proxy-Authorization 和 Proxy-Tunnel:
const http = require('http');
const { URL } = require('url');
const target = 'http://httpbin.org/ip';
const u = new URL(target);
const auth = Buffer.from(`${user}:${pass}`).toString('base64');
const options = {
hostname: host,
port: parseInt(port),
method: 'GET',
path: target,
headers: {
'Host': u.hostname,
'Proxy-Authorization': `Basic ${auth}`,
'Proxy-Tunnel': process.env.PROXY_TUNNEL || 'http-demo',
},
};
const req = http.request(options, (res) => {
console.log('status:', res.statusCode);
res.setEncoding('utf8');
res.on('data', (chunk) => process.stdout.write(chunk));
});
req.on('error', (e) => console.error('error:', e.message));
req.end();
原生 http 模块只能处理 HTTP 目标。HTTPS 目标需要通过
http-proxy-agent或https-proxy-agent实现隧道。
三种方案对比
| 方面 | axios + agent | got | 原生 http |
|---|---|---|---|
| HTTPS 支持 | ✅ | ✅ | ❌ 需要 http-proxy-agent |
| HTTPS Proxy-Tunnel | ✅ headers 参数 | ✅ agent 配置 | ❌ |
| API 简洁度 | 中等 | 简洁 | 繁琐 |
| 社区生态 | 最广泛 | 活跃 | 无依赖 |
| Keep-Alive 控制 | 复用 Agent 实例 | 复用 Agent | 默认 keepalive |
错误排查
curl -x http://$PROXY_USERNAME:$PROXY_PASSWORD@$PROXY_HOST:$PROXY_PORT https://httpbin.org/ip
| 现象 | 原因 | 解决 |
|---|---|---|
| 407 | 代理认证失败 | 确认 proxyUrl 中的用户名密码 |
| ECONNREFUSED | 代理服务器不可达 | 检查 host:port |
| ETIMEDOUT | 请求超时 | 增加 timeout 值,检查网络 |
需要企业代理方案?
我们可根据目标站点、并发规模与稳定性目标提供定制方案。