JustProxies

Examples

Node (axios · undici · fetch)

5-min readnode
Node 18+ ships fetch backed by undici. That gives you a clean proxy-agent path. Snippets for the other usual suspects below.

fetch / undici

On Node 18+ pass a dispatcher with a ProxyAgent. Works for both HTTP and HTTPS targets:

undici-fetch.jsjavascript
import { ProxyAgent } from "undici";

const dispatcher = new ProxyAgent(
  "http://USER:[email protected]:8080"
);

const r = await fetch("https://api.ipify.org", { dispatcher });
console.log(r.status, await r.text());
On Node ≤ 17 the global fetch doesn't exist; install undici directly and use request from it, or fall back to node-fetch with https-proxy-agent.

axios

axios doesn't support HTTPS-via-HTTP-proxy out of the box on the legacy proxy option — use https-proxy-agent:

axios-proxy.jsjavascript
import axios from "axios";
import { HttpsProxyAgent } from "https-proxy-agent";

const agent = new HttpsProxyAgent(
  "http://USER:[email protected]:8080"
);

const r = await axios.get("https://api.ipify.org", {
  httpAgent: agent,
  httpsAgent: agent,
  proxy: false,         // disable axios's built-in proxy handling
  timeout: 20000,
});
console.log(r.status, r.data);
proxy: false is critical
Without proxy: false, axios tries to combine its own proxy handler with the agent and you get unpredictable behaviour. Disable axios's handler explicitly when supplying an agent.

node-fetch

node-fetch-proxy.jsjavascript
import fetch from "node-fetch";
import { HttpsProxyAgent } from "https-proxy-agent";

const agent = new HttpsProxyAgent(
  "http://USER:[email protected]:8080"
);

const r = await fetch("https://api.ipify.org", { agent });
console.log(r.status, await r.text());

got

got-proxy.jsjavascript
import got from "got";
import { HttpsProxyAgent } from "https-proxy-agent";
import { HttpProxyAgent } from "http-proxy-agent";

const proxy = "http://USER:[email protected]:8080";

const r = await got("https://api.ipify.org", {
  agent: {
    http: new HttpProxyAgent(proxy),
    https: new HttpsProxyAgent(proxy),
  },
  timeout: { request: 20_000 },
});
console.log(r.statusCode, r.body);

Sticky sessions

Append the session token to the username inside the proxy URL. The whole URL embeds in the agent at construction time.

javascript
import { ProxyAgent } from "undici";
import { randomBytes } from "node:crypto";

const session = randomBytes(8).toString("hex");
const proxy = `http://USER-session-${session}:[email protected]:8080`;
const dispatcher = new ProxyAgent(proxy);

// All three calls exit through the same IP for the session lifetime.
await fetch("https://target.com/login",     { method: "POST", dispatcher });
await fetch("https://target.com/dashboard", { dispatcher });
await fetch("https://target.com/checkout",  { dispatcher });

Common pitfalls

  • Wrong protocol in the proxy URL — even for HTTPS targets the proxy URL stays http://. The CONNECT method handles the tunnel.
  • Forgetting proxy: false in axios when supplying an agent — axios will try to do both and produce weird hangs or 502s.
  • Missing httpAgent or httpsAgent — set both, even if you only call HTTPS targets. Some libraries fall through to httpAgent for the initial connection.
  • Per-request agent re-creation — keep a single agent for the lifetime of the worker. Re-creating it per request defeats keep-alive and tanks throughput.

For deeper trouble, the error reference walks through every status code we emit.

Found a gap, or something wrong?
A real human reads support email.