Built-in fetch and undici#
Node's global fetch is undici. Give it a ProxyAgent per request with the dispatcher option, or set it globally once with setGlobalDispatcher.
import { fetch, ProxyAgent, setGlobalDispatcher } from "undici";
const proxy = new ProxyAgent("http://USER-cc-us:[email protected]:9000");
// Per request
const res = await fetch("https://api.ipify.org", { dispatcher: proxy });
console.log(await res.text());
// Or globally, for every fetch in the process
setGlobalDispatcher(proxy);A ProxyAgent pools connections, so consecutive requests may reuse one connection and therefore one exit. For a fresh exit per request create the agent with pipelining: 0 and connections: 1, or simply use a different -sid- per logical session.
axios#
axios's own proxy option does not tunnel HTTPS reliably; the standard approach is an agent from https-proxy-agent and proxy: false.
import axios from "axios";
import { HttpsProxyAgent } from "https-proxy-agent";
const agent = new HttpsProxyAgent("http://USER-cc-de-city-berlin-sid-cart42-ttl-15m:[email protected]:9000");
const client = axios.create({ httpsAgent: agent, httpAgent: agent, proxy: false, timeout: 30000 });
const { data } = await client.get("https://api.ipify.org");
console.log(data);got#
import got from "got";
import { HttpsProxyAgent } from "https-proxy-agent";
const agent = new HttpsProxyAgent("http://USER-cc-us:[email protected]:9000");
const body = await got("https://api.ipify.org", { agent: { https: agent, http: agent }, timeout: { request: 30000 } }).text();
console.log(body);SOCKS5#
import { SocksProxyAgent } from "socks-proxy-agent";
// socks5h resolves the destination at the exit
const agent = new SocksProxyAgent("socks5h://USER-cc-us:[email protected]:9001");
const res = await fetch("https://api.ipify.org", { dispatcher: undefined, agent }); // node-fetch style clients take `agent`Environment variables#
undici does not read HTTPS_PROXY by default. Recent undici versions ship EnvHttpProxyAgent, which does; set it as the global dispatcher and the whole process, including third-party libraries built on fetch, goes through the proxy.
import { EnvHttpProxyAgent, setGlobalDispatcher } from "undici";
// HTTPS_PROXY=http://USER-cc-us:[email protected]:9000 NO_PROXY=localhost node app.js
setGlobalDispatcher(new EnvHttpProxyAgent());Concurrency and rotation#
- One
ProxyAgentper sticky session (different-sid-), shared by all requests of that session. - For wide rotation, keep one agent but disable connection reuse, or run N agents with N session ids and round-robin them.
- Watch
UND_ERR_SOCKETandECONNRESET: a residential exit went away; retry once, the next connection picks another.
Questions people ask#
Why does axios ignore my proxy for HTTPS?
Its built-in proxy support is limited for CONNECT tunnels. Use https-proxy-agent as httpsAgent and set proxy: false so axios does not try to handle it itself.
Can I proxy only some requests?
Yes. Pass the dispatcher or agent on the requests that need it and leave the others untouched; nothing is global unless you call setGlobalDispatcher.