API-Dokumentationen und die Entwicklertools des Browsers geben Beispielanfragen oft als cURL-Befehl an. Für einen schnellen Test im Terminal ist das ideal; müssen Sie dieselbe Anfrage aber in eine Node.js-Anwendung oder ein Scraping-Skript übertragen, müssen Sie den Befehl in JavaScript übersetzen. In diesem Beitrag erklären wir die JavaScript-Entsprechungen der meistgenutzten cURL-Optionen, zeigen Übersetzungsbeispiele, vier Wege für die Proxy-Nutzung in Node.js, die Fehlerbehandlung und häufige Fehler.
Alle Beispiele wurden mit Node.js 24, undici 8 und Axios 1.20 getestet.
Was ist das Gegenstück zu cURL in JavaScript?
Es gibt zwei Hauptoptionen:
- fetch: Ist in Browsern und seit Node.js 18 nativ eingebaut. Kein zusätzliches Paket nötig. Node.js' fetch-Implementierung nutzt im Hintergrund die Bibliothek undici.
- Axios: Eine seit Langem verwendete, populäre Bibliothek, die JSON automatisch umwandelt und Interceptor-Unterstützung für Anfragen und Antworten bietet.
Es ist auch möglich, ohne das Terminal zu verlassen, einen cURL-Befehl direkt weiterzuverwenden (mit child_process), doch dieser Weg erschwert Fehlerbehandlung und Portabilität; Sie bleiben davon abhängig, dass cURL auf der Maschine installiert ist. Mit einem nativen Client zu schreiben ist fast immer die bessere Wahl.
JavaScript-Entsprechungen der cURL-Optionen
| cURL | fetch | Axios |
|---|---|---|
curl URL | fetch(url) | axios.get(url) |
-X POST | method: "POST" | axios.post(url, daten) |
-H "Name: Wert" | headers: { Name: "Wert" } | headers: { Name: "Wert" } |
-d '{"a":1}' | body: JSON.stringify({ a: 1 }) | Objekt als zweiter Parameter |
-d "a=1&b=2" | body: new URLSearchParams({ a: 1, b: 2 }) | new URLSearchParams(...) als zweiter Parameter |
-F "datei=@a.png" | body: FormData | FormData als zweiter Parameter |
-u benutzer:passwort | Authorization: "Basic ..."-Header | auth: { username, password } |
-b "name=wert" (Cookie) | headers: { Cookie: "name=wert" } | headers: { Cookie: "name=wert" } |
-A "UA" | headers: { "User-Agent": "UA" } | headers: { "User-Agent": "UA" } |
-L (Weiterleitung folgen) | Folgt standardmäßig | Folgt standardmäßig |
-x proxy | dispatcher: new ProxyAgent(...) | httpsAgent oder proxy |
-m 20 (Timeout) | signal: AbortSignal.timeout(20000) | timeout: 20000 |
-i (Antwort-Header) | response.headers | response.headers |
-o datei | Body mit fs.writeFile schreiben | responseType: "stream" |
Beispiel: eine POST-Anfrage übersetzen
Betrachten wir folgenden cURL-Befehl:
curl -X POST https://httpbin.org/post \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TOKEN" \
-d '{"q": 1}'Mit fetch
const response = await fetch("https://httpbin.org/post", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer TOKEN",
},
body: JSON.stringify({ q: 1 }),
signal: AbortSignal.timeout(20000),
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
console.log(data.json);fetch hat eine Besonderheit: Gibt der Server 404 oder 500 zurück, wird keine Exception geworfen. Ob die Antwort erfolgreich war, müssen Sie selbst über response.ok prüfen. Ein Netzwerkfehler (DNS, Verbindungsabbruch, Timeout) kommt hingegen als Exception.
Mit Axios
npm install axiosimport axios from "axios";
const { data } = await axios.post(
"https://httpbin.org/post",
{ q: 1 },
{ headers: { Authorization: "Bearer TOKEN" }, timeout: 20000 },
);
console.log(data.json);Axios wandelt das Objekt selbst in JSON um, fügt den Content-Type-Header hinzu und wirft bei Antworten außerhalb des 2xx-Bereichs eine Exception.
Beispiel: Formularübertragung und Datei-Upload
Eine Formularübertragung im Format -d "a=1&b=2" wird in JavaScript mit URLSearchParams abgebildet:
const response = await fetch("https://httpbin.org/post", {
method: "POST",
body: new URLSearchParams({ a: "1", b: "2" }),
});
console.log((await response.json()).form);Wird ein URLSearchParams-Body übergeben, setzt fetch den Content-Type-Header selbst auf application/x-www-form-urlencoded. Für Datei-Uploads (-F) wird FormData verwendet, auch hier wird die Boundary automatisch eingefügt. Ein Detail: Beziehen Sie die fetch-Funktion aus dem undici-Paket, nehmen Sie auch die FormData-Klasse aus demselben Paket; die eingebaute FormData passt nicht zu undicis fetch, und der Body wird dann als reiner Text übertragen.
import { openAsBlob } from "node:fs";
const form = new FormData();
form.append("datei", await openAsBlob("./a.png"), "a.png");
const response = await fetch("https://httpbin.org/post", { method: "POST", body: form });
console.log(Object.keys((await response.json()).files));Vier Wege, in Node.js einen Proxy zu nutzen
Bei cURL ist der Proxy eine einzelne Option -x. In Node.js hängt die Methode davon ab, welchen Client Sie verwenden.
1. fetch und undici ProxyAgent
npm install undiciimport { fetch, ProxyAgent } from "undici";
const dispatcher = new ProxyAgent("http://benutzer:passwort@pr.proxynet.io:8000");
const response = await fetch("https://httpbin.org/ip", { dispatcher });
console.log(await response.text());Beachten Sie, dass wir auch die fetch-Funktion aus dem undici-Paket importieren. Node.js' eingebautes fetch basiert ebenfalls auf undici, doch da im separat installierten Paket ein Versionsunterschied bestehen kann, ist es am sichersten, beide aus demselben Paket zu beziehen.
2. Globale Einstellung für alle fetch-Aufrufe
Soll jeder fetch-Aufruf der Anwendung denselben Proxy verwenden, können Sie einen globalen Dispatcher definieren:
import { ProxyAgent, setGlobalDispatcher } from "undici";
setGlobalDispatcher(new ProxyAgent("http://benutzer:passwort@pr.proxynet.io:8000"));
const response = await fetch("https://httpbin.org/ip");
console.log(await response.text());Diese Methode erfasst auch fetch-Aufrufe, die aus einer Bibliothek eines Drittanbieters heraus erfolgen; ohne den Quellcode der Bibliothek anzurühren, leiten Sie deren Traffic über den Proxy.
3. Über eine Umgebungsvariable, ohne Codeänderung
Aktuelle Node.js-Versionen können bei aktivierter Variable NODE_USE_ENV_PROXY für das eingebaute fetch die üblichen Proxy-Umgebungsvariablen lesen:
NODE_USE_ENV_PROXY=1 HTTPS_PROXY="http://benutzer:passwort@pr.proxynet.io:8000" node anwendung.mjsDiese Methode ist nützlich, um ein bestehendes Skript ohne Quellcode-Änderung über einen Proxy zu leiten. Auch die Variable NO_PROXY wird gelesen; interne Netzwerkadressen können Sie dieser Liste hinzufügen, um sie vom Proxy auszunehmen. Ob die Funktion in Ihrer Version verfügbar ist, prüfen Sie in der Node.js-Dokumentation.
4. Axios und HTTPS-Ziele
Die eingebaute proxy-Option von Axios funktioniert für unverschlüsselte HTTP-Adressen problemlos:
const { data } = await axios.get("http://httpbin.org/ip", {
proxy: {
protocol: "http",
host: "pr.proxynet.io",
port: 8000,
auth: { username: "benutzer", password: "passwort" },
},
});Bei HTTPS-Adressen ist ein Proxy-Agent verlässlicher:
npm install https-proxy-agentimport axios from "axios";
import { HttpsProxyAgent } from "https-proxy-agent";
const httpsAgent = new HttpsProxyAgent("http://benutzer:passwort@pr.proxynet.io:8000");
const { data } = await axios.get("https://httpbin.org/ip", { httpsAgent, proxy: false });
console.log(data);Die Zeile proxy: false ist wichtig; sie schaltet Axios' eigene Proxy-Logik ab und überlässt den Tunnel vollständig dem Agenten. Erstellen Sie den Agenten einmal und binden ihn mit axios.create({ httpsAgent, proxy: false }) an eine Instanz, müssen Sie ihn nicht bei jedem Aufruf erneut schreiben.
Die vier Methoden im Vergleich
| Methode | Umfang | Codeänderung | Geeignet für |
|---|---|---|---|
undici ProxyAgent | Einzelner Aufruf | dispatcher bei jedem Aufruf | Unterschiedlicher Proxy pro Anfrage |
setGlobalDispatcher | Alle fetch-Aufrufe | Eine Zeile beim Start | Ein Proxy für die gesamte Anwendung |
NODE_USE_ENV_PROXY | Alle eingebauten fetch-Aufrufe | Keine | Bestehendes Skript, Deployment-Umgebung |
| Axios + Agent | Axios-Instanz | httpsAgent + proxy: false | Wenn Axios im Projekt genutzt wird |
Wiederholung und Nebenläufigkeit
In einem echten Scraping-Skript scheitern Anfragen gelegentlich; der Proxy erreicht das Ziel nicht, oder die Website liefert 429. Die folgende Hilfsfunktion wiederholt eine fehlgeschlagene Anfrage mit exponentiellem Backoff und begrenzt die Anzahl gleichzeitig offener Anfragen:
import { fetch, ProxyAgent } from "undici";
const dispatcher = new ProxyAgent("http://benutzer:passwort@pr.proxynet.io:8000");
async function getir(url, deneme = 3) {
for (let i = 0; i < deneme; i++) {
try {
const r = await fetch(url, { dispatcher, signal: AbortSignal.timeout(20000) });
if (r.status === 429 || r.status >= 500) throw new Error(`HTTP ${r.status}`);
return await r.text();
} catch (hata) {
if (i === deneme - 1) throw hata;
await new Promise((coz) => setTimeout(coz, 1000 * 2 ** i));
}
}
}
async function topluGetir(urls, esZamanli = 5) {
const sonuclar = [];
for (let i = 0; i < urls.length; i += esZamanli) {
const grup = urls.slice(i, i + esZamanli);
sonuclar.push(...(await Promise.allSettled(grup.map(getir))));
}
return sonuclar;
}
const urls = Array.from({ length: 20 }, (_, i) => `https://httpbin.org/get?i=${i}`);
const sonuclar = await topluGetir(urls);
console.log(sonuclar.filter((s) => s.status === "fulfilled").length, "erfolgreich");Promise.allSettled verhindert, dass der Fehler einer einzelnen Anfrage die ganze Gruppe zu Fall bringt; Sie können jedes Ergebnis einzeln prüfen. Die Wartezeit verdoppelt sich bei jedem Versuch; in konstanten Abständen zu beharren verschärft eine Website mit Rate-Limiting nur weiter.
Häufige Fehler
Sonderzeichen im Passwort
Enthält Ihr Proxy-Passwort Zeichen wie @, : oder /, kodieren Sie diese innerhalb der Adresse mit encodeURIComponent. Andernfalls wird die Adresse falsch geparst und Sie erhalten den Fehler "407 Proxy Authentication Required".
Anfragen ohne Timeout
In Standardeinstellungen kann eine Anfrage lange auf eine Antwort warten und Ihr Skript bleibt hängen. Setzen Sie bei fetch mit AbortSignal.timeout, bei Axios mit timeout für jede Anfrage eine Zeitgrenze.
Zu viele gleichzeitige Anfragen
Mit Promise.all Hunderte Anfragen auf einmal zu starten, überfordert sowohl Ihre eigenen Verbindungsgrenzen als auch führt es dazu, dass Sie auf der Zielseite ins Rate-Limiting geraten. Begrenzen Sie die Nebenläufigkeit wie oben gezeigt in kleinen Gruppen. Bei Aufgaben mit vielen Anfragen senkt Rotierender Proxy das Risiko einer Sperrung, indem der Traffic auf verschiedene IPs verteilt wird.
agent an das eingebaute fetch übergeben
In Node.js' alter http.request-API wird der Proxy über die Option agent übergeben. Das eingebaute fetch kennt diese Option nicht und ignoriert sie stillschweigend; die Anfrage geht dann ohne Proxy hinaus. Der richtige Schlüssel für fetch ist dispatcher.
Browser-Header unverändert kopieren
Aus den Entwicklertools kopierte Anfragen tragen browserspezifische Header wie sec-ch-ua, sec-fetch-*. In Node.js müssen diese nicht gesendet werden, und manche können auf der Zielseite als Inkonsistenz gewertet werden; lassen Sie nur wirklich benötigte Header übrig.
Seiten, für die eine HTTP-Anfrage nicht ausreicht
fetch und Axios beziehen nur das vom Server zurückgegebene HTML. Wird der Inhalt im Browser nachträglich per JavaScript geladen, finden Sie auf der Seite nicht, wonach Sie suchen. In diesem Fall müssen Sie entweder die Hintergrund-API-Anfrage finden oder eine Browser-Automatisierung nutzen. Die Optionen haben wir in Web Scraping: JavaScript oder Python? verglichen; die Proxy-Nutzung mit Puppeteer zeigen wir in Puppeteer und CAPTCHA.
fetch oder Axios?
- Wählen Sie fetch: wenn Sie keine zusätzliche Abhängigkeit wollen, der Code sowohl im Browser als auch in Node.js laufen soll, oder Sie von undicis Verbindungsmanagement profitieren möchten.
- Wählen Sie Axios: wenn Sie Annehmlichkeiten wie automatische JSON-Umwandlung, Interceptor oder Exceptions bei Antworten außerhalb des 2xx-Bereichs brauchen, oder es im Projekt bereits genutzt wird.
Der Unterschied zwischen beiden ist eher Gewohnheit als Funktionalität. In einem neuen Projekt mit fetch zu beginnen hält die Anzahl der Abhängigkeiten niedrig; in einem großen Axios-Projekt gibt es keinen Grund, zu fetch zu wechseln.
Häufig gestellte Fragen
Kann ich einen cURL-Befehl automatisch in JavaScript übersetzen?
In den Entwicklertools des Browsers können Sie im Netzwerk-Tab eine Anfrage per Rechtsklick mit "Copy as fetch" direkt als fetch-Code kopieren. Prüfen Sie den entstandenen Code trotzdem; browserspezifische Header können in Node.js überflüssig sein.
Kann ich in Node.js einen SOCKS5-Proxy nutzen?
Das eingebaute fetch und der undici-ProxyAgent sind für HTTP-Proxys gedacht. Für SOCKS5 müssen Sie mit einem zusätzlichen Paket wie socks-proxy-agent einen Agenten definieren. Bei cURL wird das Schema socks5h:// dagegen direkt unterstützt; Details in unserem Beitrag Wie nutzt man einen Proxy mit cURL?.
Kann im Browser laufendes JavaScript einen Proxy definieren?
Nein. Das fetch im Browser erlaubt es nicht, die Proxy-Einstellung über Code zu ändern; der Proxy wird in den Einstellungen des Browsers oder des Betriebssystems definiert. Proxy-Verwaltung aus dem Code heraus ist Serverumgebungen wie Node.js vorbehalten. Für Proxy auf Browserebene werden Erweiterungen wie SwitchyOmega genutzt.
Wie behalte ich Cookies zwischen Anfragen bei?
Das eingebaute fetch speichert keine Cookies. Sie müssen den Set-Cookie-Header aus der Antwort lesen und ihn der nächsten Anfrage als Cookie-Header hinzufügen, oder mit Axios ein auf tough-cookie basierendes Cookie-Jar verwenden. Denken Sie daran, dass bei angemeldeten Abläufen auch die IP konstant bleiben muss; Sticky-Proxy ist genau dafür konzipiert.
Kann ich bei jeder Anfrage einen anderen Proxy nutzen?
Ja. Mit undici können Sie jedem Aufruf einen anderen ProxyAgent geben. Statt die Liste selbst zu verwalten, ist es jedoch einfacher, einen Rotating-Proxy zu nutzen: eine Adresse, bei jeder Verbindung eine andere ausgehende IP.
Funktioniert derselbe Code auch in TypeScript?
Ja. undici und Axios liefern Typdefinitionen mit; für die dispatcher-Option müssen Sie undicis eigenen fetch-Typ verwenden, da die Typdefinition des eingebauten fetch diese Option nicht kennt.
Fazit
cURL-Befehle lassen sich in JavaScript eins zu eins mit fetch oder Axios abbilden. Für Proxys in Node.js gibt es vier Wege: den undici-ProxyAgent, einen globalen Dispatcher, die Umgebungsvariable NODE_USE_ENV_PROXY und für Axios einen Proxy-Agenten. Timeout, Fehlerprüfung, Wiederholung mit exponentiellem Backoff und eine von Anfang an eingebaute Nebenläufigkeitsgrenze machen Ihre Skripte deutlich zuverlässiger. Passende Pakete für Web-Traffic finden Sie auf unserer Seite HTTPS-Proxy.




