Node.js HTTP Client Tunnel Proxy: axios / got / http Comparison
Three Node.js HTTP clients (axios + https-proxy-agent, got, native http) implementing four tunnel proxy scenarios with 16Yun Crawler Proxy.
16Yun Engineering TeamJun 1, 20261 min read
Node.js Proxy Ecosystem
Node.js HTTP clients use http-proxy-agent / https-proxy-agent for proxy support. https-proxy-agent supports custom headers at the CONNECT stage for Proxy-Tunnel.
Setup
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
const axios = require('axios');
const { HttpsProxyAgent } = require('https-proxy-agent');
const proxyUrl = `http://${user}:${pass}@${host}:${port}`;
const tunnelVal = process.env.PROXY_TUNNEL || 'axios-demo';
// Scenario C-HTTPS: Proxy-Tunnel via agent options
const agent = new HttpsProxyAgent(proxyUrl, {
headers: { 'Proxy-Tunnel': tunnelVal }, // Sent during CONNECT
});
async function main() {
for (let i = 1; i <= 3; i++) {
const resp = await axios.get('https://httpbin.org/ip', { httpsAgent: agent });
console.log(`Request ${i}: ${resp.data.origin}`);
}
}
main();
All Four Scenarios
// A: Force new — new agent each request
const agent = new HttpsProxyAgent(proxyUrl);
await axios.get(url, { httpsAgent: agent, headers: { 'Connection': 'close' } });
// B: Keep-Alive — reuse agent
const agentK = new HttpsProxyAgent(proxyUrl);
for (let i = 0; i < 3; i++) {
await axios.get(url, { httpsAgent: agentK, headers: { 'Connection': 'keep-alive' } });
}
// C-HTTP: Proxy-Tunnel on request
await axios.get('http://httpbin.org/ip', {
httpAgent: new HttpProxyAgent(proxyUrl),
headers: { 'Proxy-Tunnel': tunnelVal },
});
// C-HTTPS: Proxy-Tunnel via agent options
const tunnelAgent = new HttpsProxyAgent(proxyUrl, {
headers: { 'Proxy-Tunnel': tunnelVal },
});
await axios.get('https://httpbin.org/ip', { httpsAgent: tunnelAgent });
got
const got = require('got');
const { HttpsProxyAgent } = require('https-proxy-agent');
const agent = {
https: new HttpsProxyAgent(proxyUrl, {
headers: { 'Proxy-Tunnel': process.env.PROXY_TUNNEL || 'got-demo' },
}),
};
const resp = await got('https://httpbin.org/ip', { agent });
console.log(JSON.parse(resp.body).origin);
Native http Module
HTTP targets only — native module can't handle HTTPS CONNECT natively:
const http = require('http');
const auth = Buffer.from(`${user}:${pass}`).toString('base64');
const options = {
hostname: host, port: parseInt(port), method: 'GET',
path: 'http://httpbin.org/ip',
headers: {
'Host': 'httpbin.org',
'Proxy-Authorization': `Basic ${auth}`,
'Proxy-Tunnel': process.env.PROXY_TUNNEL || 'http-demo',
},
};
const req = http.request(options, (res) => {
res.setEncoding('utf8');
res.on('data', (chunk) => process.stdout.write(chunk));
});
req.end();
Comparison
| Aspect | axios + agent | got | Native http |
|---|---|---|---|
| HTTPS | ✅ | ✅ | ❌ Needs agent |
| HTTPS Tunnel | ✅ headers option | ✅ agent config | ❌ |
| API | Moderate | Clean | Verbose |
| Ecosystem | Largest | Growing | No deps |
curl -x http://$PROXY_USERNAME:$PROXY_PASSWORD@$PROXY_HOST:$PROXY_PORT https://httpbin.org/ip
Need an enterprise proxy plan?
We can tailor architecture to your target domains, concurrency, and reliability goals.