Node.js (fetch/undici, axios, got)
Route Node.js HTTP traffic through mobile, residential and static ISP proxies with undici's ProxyAgent, axios and SOCKS agents, with rotation and concurrency control.
On this page
Node.js 18+ ships fetch, implemented by undici. It does not read HTTP_PROXY by default; pass a proxy agent explicitly.
fetch with undici's ProxyAgent#
npm install undici
import { fetch, ProxyAgent } from "undici";
const dispatcher = new ProxyAgent({
uri: "http://fr.mobile.gw.proxuno.com:10421",
token: `Basic ${Buffer.from("m_k3v9q2xa:Hq7Lr2Nw8Zt4Bc6D").toString("base64")}`,
connectTimeout: 10_000,
});
const res = await fetch("https://api.ipify.org?format=json", { dispatcher });
console.log(await res.json());
You can also pass credentials inline — new ProxyAgent("http://m_k3v9q2xa:[email protected]:10421") — undici turns them into a Proxy-Authorization header. Reuse one agent for all requests through the same proxy: it keeps a connection pool.
To apply a proxy to every fetch in the process:
import { setGlobalDispatcher, ProxyAgent } from "undici";
setGlobalDispatcher(new ProxyAgent(process.env.PROXY_URL));
axios#
axios has built-in proxy support for HTTP proxies, but its HTTPS-over-proxy handling is unreliable. Use an agent instead:
npm install axios https-proxy-agent
import axios from "axios";
import { HttpsProxyAgent } from "https-proxy-agent";
const agent = new HttpsProxyAgent(process.env.PROXY_URL); // http://user:pass@host:port
const client = axios.create({
httpAgent: agent,
httpsAgent: agent,
proxy: false, // disable axios' own proxy logic, the agent handles it
timeout: 30_000,
});
const { data } = await client.get("https://api.ipify.org?format=json");
console.log(data);
SOCKS5#
npm install socks-proxy-agent
import axios from "axios";
import { SocksProxyAgent } from "socks-proxy-agent";
const agent = new SocksProxyAgent("socks5h://m_k3v9q2xa:[email protected]:20421");
const { data } = await axios.get("https://api.ipify.org?format=json", { httpAgent: agent, httpsAgent: agent, proxy: false });
socks5h resolves DNS on the proxy. The SOCKS port of a mobile proxy is its HTTP port + 10000.
got#
import got from "got";
import { HttpsProxyAgent } from "hpagent";
const agent = new HttpsProxyAgent({ proxy: process.env.PROXY_URL, keepAlive: true, maxSockets: 10 });
const body = await got("https://api.ipify.org?format=json", { agent: { https: agent }, timeout: { request: 30_000 } }).json();
Residential with sticky sessions#
import { randomBytes } from "node:crypto";
import { ProxyAgent, fetch } from "undici";
const LOGIN = "px4k2m9q7a";
const PASSWORD = process.env.RESI_PASSWORD;
function resiAgent({ country = "eu", city, stickyMinutes } = {}) {
let user = `${LOGIN}-country-${country}`;
if (city) user += `-city-${city}`;
if (stickyMinutes) user += `-session-${randomBytes(4).toString("hex")}-ttl-${stickyMinutes}`;
return new ProxyAgent(`http://${user}:${PASSWORD}@resi.gw.proxuno.com:7000`);
}
const dispatcher = resiAgent({ country: "es", city: "madrid", stickyMinutes: 15 });
for (const path of ["/login", "/account", "/orders"]) {
const res = await fetch(`https://example.com${path}`, { dispatcher });
console.log(path, res.status);
}
Concurrency and rotation#
const API = "https://proxuno.com/api/v1";
const auth = { Authorization: `Bearer ${process.env.PROXUNO_API_KEY}` };
async function rotate(id) {
for (;;) {
const res = await fetch(`${API}/proxies/${id}/rotate`, { method: "POST", headers: auth });
if (res.status === 429) {
await new Promise((r) => setTimeout(r, Number(res.headers.get("retry-after") || 10) * 1000));
continue;
}
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
return body.data.ip;
}
}
// run at most 10 requests in flight through one mobile proxy
async function pool(items, limit, worker) {
const queue = [...items];
await Promise.all(Array.from({ length: limit }, async () => {
while (queue.length) await worker(queue.shift());
}));
}
Troubleshooting#
| Symptom | Fix |
|---|---|
UND_ERR_ABORTED / 407 |
Credentials or expired proxy. Test the same line with cURL. |
| axios hangs on HTTPS targets | Set proxy: false and use an agent, as above. |
ECONNRESET right after a rotation |
The modem reconnects for 5–10 s; retry. |
| Requests do not go through the proxy | fetch ignores HTTP_PROXY; pass dispatcher or set a global dispatcher. |
Something unclear, outdated or wrong on this page? Tell us — documentation issues are fixed in the next release at the latest.
Report an issue with this page