# Roteren met residentiële proxy's in Node.js: undici, axios, got en SOCKS5

> Roteren met residentiële proxy's in Node.js: undici ProxyAgent met fetch, axios en got met proxy agents, SOCKS5, per-host limieten. Syntax-gecontroleerde code.

- URL: https://crawlrelay.com/nl/docs/node/
- Laatst bijgewerkt: 2026-10-13
- Publisher: CrawlRelay (https://crawlrelay.com)

Node’s ingebouwde fetch negeert proxy-instellingen tenzij je een dispatcher meegeeft. Dit zijn de patronen die werken, bibliotheek per bibliotheek, plus een limiter per host zonder afhankelijkheden.

**Kort antwoord — Hoe gebruik ik een roterende proxy in Node.js?**

Gebruik fetch, maak een undici `ProxyAgent` voor `http://gw.crawlrelay.com:7777` en geef dat door als `dispatcher`. Bij axios of got geef je een proxy-agent zoals `https-proxy-agent` of `hpagent` mee, en stel je `proxy: false` in bij axios. **CrawlRelay** mobiele 4G-proxy's lezen het land en sessie van de gebruikersnaam, van US$ 0,50/GB. Betaald in crypto, zonder KYC.

## Node.js setup in een oogopslag

| Attribuut | Waarde |
| --- | --- |
| fetch / undici | `new ProxyAgent({ uri, token })`, dan `fetch(url, { dispatcher })` |
| axios | `httpsAgent: new HttpsProxyAgent(url)` en `proxy: false` |
| got | `agent: { https: new HttpsProxyAgent({ proxy }) }` van hpagent |
| SOCKS5 | `socks-proxy-agent` met een `socks5h://` URL op poort 7778 |
| Nieuw IP per verzoek | Een nieuwe agent of een nieuwe sessie-ID per verzoek; gepoolde connecties behouden hun exit |
| Moduleformaat | Voorbeelden zijn ES-modules (`.mjs` of `"type": "module"`) met top-level await |

## Hoe gebruik ik een proxy met Node's fetch?

De globale `fetch` van Node is gebouwd op undici maar leest standaard geen `HTTP_PROXY` of `HTTPS_PROXY`. Installeer undici en geef een `ProxyAgent` mee als dispatcher. Het veld `token` verstuurt de inloggegevens als een `Proxy-Authorization` header, zodat er nooit een wachtwoord in een URL verschijnt die gelogd kan worden.

*undici ProxyAgent met fetch*

```javascript
import { ProxyAgent, fetch } from "undici";

const credentials = Buffer.from("USERNAME-country-us:PASSWORD").toString("base64");
const dispatcher = new ProxyAgent({
  uri: "http://gw.crawlrelay.com:7777",
  token: `Basic ${credentials}`,
});

const res = await fetch("https://api.ipify.org?format=json", {
  dispatcher,
  signal: AbortSignal.timeout(30000),
});
console.log(res.status, await res.json());
await dispatcher.close();
```

## Hoe gebruik ik een proxy met axios?

Vertrouw niet op axios’s eigen `proxy` optie voor HTTPS-sites: deze stuurt het verzoek naar de proxy zonder CONNECT-tunnel, wat veel proxies weigeren. Schakel het uit met `proxy: false` en geef een agent mee die een juiste tunnel opent.

*axios + https-proxy-agent*

```javascript
import axios from "axios";
import { HttpsProxyAgent } from "https-proxy-agent";

const agent = new HttpsProxyAgent("http://USERNAME-country-de:PASSWORD@gw.crawlrelay.com:7777");
const client = axios.create({ httpsAgent: agent, httpAgent: agent, proxy: false, timeout: 30000 });

const { data } = await client.get("https://api.ipify.org?format=json");
console.log(data.ip);
```

## Hoe gebruik ik een proxy met got?

got gebruikt één agent per protocol. hpagent volgt Node’s `http.Agent`: keep-alive is uit tenzij je `keepAlive: true` meegeeft. Laat het uit of zet `keepAlive: false` zoals hieronder wanneer je elk verzoek op een nieuwe verbinding wilt, en dus meestal via een nieuwe exit.

*got + hpagent*

```javascript
import got from "got";
import { HttpsProxyAgent } from "hpagent";

const proxy = "http://USERNAME-country-fr:PASSWORD@gw.crawlrelay.com:7777";
const body = await got("https://api.ipify.org", {
  agent: { https: new HttpsProxyAgent({ proxy, keepAlive: false }) },
  timeout: { request: 30000 },
  retry: { limit: 2, statusCodes: [429, 502, 503, 504] },
}).text();
console.log(body);
```

## Hoe gebruik ik SOCKS5 in Node.js?

Gebruik `socks-proxy-agent` met het `socks5h://` schema zodat de hostnaam bij de exit wordt opgelost. Het werkt met Node’s `http` en `https` modules en met elke bibliotheek die een agent accepteert.

*socks-proxy-agent met node:https*

```javascript
import https from "node:https";
import { SocksProxyAgent } from "socks-proxy-agent";

const agent = new SocksProxyAgent("socks5h://USERNAME-country-gb:PASSWORD@gw.crawlrelay.com:7778");

const req = https.get("https://api.ipify.org", { agent, timeout: 30000 }, (res) => {
  let body = "";
  res.on("data", (chunk) => (body += chunk));
  res.on("end", () => console.log(res.statusCode, body));
});
req.on("timeout", () => req.destroy(new Error("timeout after 30 s")));
req.on("error", (err) => console.error(err.code, err.message));
```

## Hoe beperk ik gelijktijdigheid per host zonder bibliotheek?

`Promise.all` over 10.000 URL’s opent 10.000 verzoeken tegelijk. Een kleine limiter per hostnaam houdt elk siteverzoek op een netjes niveau terwijl de crawl geheel parallel loopt. De onderstaande versie heeft geen afhankelijkheden en werkt met elke client hierboven.

*Limiter per host + undici*

```javascript
import { ProxyAgent, fetch } from "undici";

const PER_HOST = 4;
const active = new Map();
const waiting = new Map();
const dispatcher = new ProxyAgent("http://USERNAME-country-us:PASSWORD@gw.crawlrelay.com:7777");

async function withHostSlot(url, task) {
  const host = new URL(url).hostname;
  while ((active.get(host) ?? 0) >= PER_HOST) {
    await new Promise((resolve) => {
      if (!waiting.has(host)) waiting.set(host, []);
      waiting.get(host).push(resolve);
    });
  }
  active.set(host, (active.get(host) ?? 0) + 1);
  try {
    return await task();
  } finally {
    active.set(host, active.get(host) - 1);
    waiting.get(host)?.shift()?.();
  }
}

const urls = ["https://example.com/", "https://example.org/", "https://example.net/"];
const results = await Promise.all(
  urls.map((url) =>
    withHostSlot(url, async () => {
      const res = await fetch(url, { dispatcher, signal: AbortSignal.timeout(30000) });
      return [url, res.status, (await res.arrayBuffer()).byteLength];
    }).catch((err) => [url, err.name, 0])
  )
);
console.table(results);
await dispatcher.close();
```

## Waarom krijg ik twee keer hetzelfde IP of ECONNRESET?

Agents poolen connecties, en een gepoolde verbinding behoudt de exit waarmee hij geopend is. Voor een nieuw IP bij elk verzoek maak je een nieuwe agent per verzoek en sluit je die daarna, zet je keep-alive uit in de agent, of zet je een unieke `-session-<id>` in elke gebruikersnaam van het verzoek.

`ECONNRESET` en `socket hang up` komen meestal door het hergebruiken van een gepoolde socket die de andere kant al gesloten heeft, of door een exit die is weggevallen. Probeer GET-verzoeken één keer opnieuw op een nieuwe verbinding. De [connection reset pagina](https://crawlrelay.com/nl/docs/errors/connection-reset/) behandelt de details.

## Node.js en proxies: vragen

### Ondersteunt Node.js fetch HTTP_PROXY?

Niet standaard in de versies die de meeste projecten nu gebruiken: de globale fetch negeert proxy-omgeving variabelen tenzij je een dispatcher meegeeft. Gebruik een undici `ProxyAgent` zoals hierboven getoond, of stel een globale dispatcher in met undici’s `setGlobalDispatcher()` als elk verzoek in het proces via de proxy moet verlopen.

### Waarom faalt axios bij HTTPS-sites achter een proxy?

De ingebouwde `proxy` optie van axios stuurt HTTPS-verzoeken naar de proxy in een vorm die veel proxies weigeren, in plaats van een CONNECT-tunnel te openen. Zet `proxy: false` en geef een `HttpsProxyAgent` als `httpsAgent` mee. Het verzoek gaat dan door een juiste tunnel en TLS blijft tussen jouw code en de site.

### Hoe verstuur ik verschillende landen vanuit één Node.js proces?

Maak per land een agent aan, elk met een eigen gebruikersnaam zoals `USERNAME-country-de` of `USERNAME-country-jp`, en kies per verzoek de juiste agent. Agents zijn goedkoop, en door ze apart te houden houd je ook hun connectiepools, en dus hun exits, gescheiden.

### Welke timeout moet ik instellen in Node.js?

Stel er altijd één in: `AbortSignal.timeout(30000)` voor fetch, `timeout: 30000` voor axios, `timeout: { request: 30000 }` voor got. Dertig seconden is geschikt voor HTML-pagina’s; geef trage doelen en mobiele exits tot 60 seconden, en probeer één keer opnieuw op een nieuwe verbinding in plaats van langer te wachten.

**Verbind je Node.js crawler** US$ 5,94 voor 10 GB, US$ 0,50/GB van 50 GB. [Zie prijslijst](https://crawlrelay.com/nl/pricing/) · [Puppeteer gids](https://crawlrelay.com/nl/docs/puppeteer/)

---

CrawlRelay: CrawlRelay is een developer-first dienst met roterende residentiële proxy's en mobiele 4G-proxy's voor scrapers en AI-datastromen: niet-vervalverkeer op basis van pay-as-you-go vanaf US$ 0,50/GB, betaald in crypto, zonder ID-upload. Zonder KYC — geen ID, geen selfie, geen documenten. Betaal met crypto.
