Das Absenden von HTTP-Anfragen ist eine der wichtigsten Funktionen jeder modernen Programmiersprache. Node.js bildet da keine Ausnahme, doch bisher war diese Funktion auf viel zu viele der verfügbaren npm-Pakete verteilt. Node-Fetch bietet hierfür eine Alternative, indem es die native Fetch-API nutzt, die derzeit von den meisten Browsern unterstützt wird.
Einführung in die Node-Fetch-API
Bevor ich Ihnen etwas über die Node-Fetch-API erzähle, muss ich Ihnen kurz erklären, was eine HTTP-Anfrage ist. Der Zweck einer HTTP-Anfrage besteht darin, Informationen von URLs im gesamten Internet abzurufen. Ein einfaches Beispiel für eine HTTP-Anfrage ist der Zugriff auf eine Website.
Während HTTP-Anfragen früher mit XMLHttpRequest oder XHR-Objekten durchgeführt wurden, unterstützen heutzutage alle modernen Browser die Fetch-API aus JavaScript. Dies ermöglicht es Programmierern, die Anfragen mit einer viel einfacheren und übersichtlicheren Syntax zu erstellen. Allerdings fehlte die Fetch-API lange Zeit in der serverseitigen Sprache Node.JS, was Raum für andere maßgeschneiderte Pakete ließ, die diese Funktion übernehmen, wie beispielsweise: Axios, GOT und viele andere.
Node-Fetch entspricht der Fetch-API aus JavaScript und ist nun endlich auch in Node.JS verfügbar.
Voraussetzungen für die Verwendung der Node-Fetch-API
Da es sich um ein Node.JS-Tutorial handelt, musst du natürlich zunächst Node.JS installiert haben. Falls du es noch nicht hast, kannst du es über diesen Link herunterladen und installieren.
Node.js hat erst ab Version 17.5 experimentelle Unterstützung für die Fetch-API veröffentlicht. Du benötigst also mindestens die Version 17.5 von Node.JS. Außerdem musst du beim Ausführen deiner Skripte das Flag –experimental-fetch verwenden.
Wenn du eine ältere Version von Node.JS hast, kannst du das n-Paket verwenden, um auf die neueste Version umzusteigen. N ist ein npmjs-Paket, das ausschließlich dazu dient, zwischen Node- und npm-Versionen zu wechseln. Um es zu installieren und auf die neueste Version umzusteigen, führe folgende Schritte aus:
npm install -g nn latest
Der Befehl „n latest“ installiert die neueste Version von Node.js. Um Ihre Node.js-Version zu überprüfen, führen Sie einfach diesen Befehl aus:
node –version
So verwenden Sie Node-Fetch
Das Senden einer HTTP-Anfrage ist in jeder Programmiersprache ein asynchroner Vorgang, da das Empfangen der Antwort auf die Anfrage Zeit in Anspruch nimmt. Es gibt zwei Ansätze, wie Sie mit asynchronen Vorgängen umgehen können. Sie können entweder auf die Antwort warten und dann mit Ihrem Code fortfahren oder Ihren Code parallel ausführen.
Node-Fetch unterstützt sowohl synchrone als auch asynchrone Funktionsaufrufe.
GET-Anfragen in Node-Fetch
Um eine einfache GET-Anfrage zu stellen und den Body aus der Antwort zu extrahieren, können Sie den folgenden Code verwenden:
fetch('https://www.webscrapingapi.com/')
.then((response) => response.text())
.then((body) => {
console.log(body);
});Um diesen Code auszuführen, sollten Sie ihn in einer Datei namens node-fetch-example.js speichern und ihn aus demselben Ordner mit folgendem Befehl ausführen: node --experimental-fetch node-fetch-example.js. Beachten Sie, dass Sie bei der Ausführung eine Warnung erhalten, die besagt: „Die Fetch-API ist eine experimentelle Funktion“. Dies ist normal, da es sich zum Zeitpunkt der Erstellung dieses Artikels um eine experimentelle Funktion handelt.
Der vorstehende Code wartet nicht auf den Abschluss der Anfrage, bevor er seine Ausführung fortsetzt. Das bedeutet, dass jeder Code unterhalb dieses Codes sofort ausgeführt wird, ohne auf den Abschluss des Fetch-Vorgangs zu warten. Wenn Sie beispielsweise unterhalb des Codes ein console.log(„Something“); einfügen, sieht die Ausgabe bei Ausführung des Skripts wie folgt aus:
Um den obigen Code näher zu erläutern: Sie werden feststellen, dass wir die „then“-Funktion zweimal verwenden. Das erste „then“ wird ausgeführt, sobald wir eine Antwort von der HTTP-Anfrage erhalten, und es ordnet diese Antwort dem Inhalt der Methode response.text() zu (die den Hauptteil der Antwort zurückgibt). Da die Methode response.text() jedoch ebenfalls asynchron ist, müssen wir im zweiten „then“ auf ihre Antwort warten, wobei body dem Ergebnis des Promises von response.text() entspricht.
Sie können die Fetch-API auch mit „await“ aufrufen, wie wir es im folgenden Beispiel tun:
(async () => {
const response = await fetch('https://webscrapingapi.com');
const body = await response.text();
console.log(body);
})();Dies liefert eine noch bessere Erklärung dafür, wie die Fetch-API funktioniert und auf welche Promises Sie warten müssen. Im weiteren Verlauf dieses Artikels werden wir die Fetch-API mit „await“ verwenden, da dies eine übersichtlichere Syntax für den Code ermöglicht.
Header an die Anfrage senden
Eine weitere Funktion, die du beim Senden von Anfragen benötigst, ist die Möglichkeit, die Header der von dir gestellten Anfrage festzulegen. Dazu kannst du die Header im zweiten Parameter der Fetch-API wie folgt hinzufügen:
(async () => {
const response = await fetch('http://httpbin.org/headers', {
headers: {
'my-custom-header': 'my-header-value'
}
});
const body = await response.text();
console.log(body);
})();Neben den Headern gibt es noch viele weitere Optionen, die du im zweiten Parameter der Fetch-API senden kannst. Um sie alle zu sehen, schau dir die Dokumentation der Fetch-API (die auf der Client-Seite verwendete) an.
POST-Anfragen in Node-Fetch
Eine weitere wichtige Option der Fetch-API ist die Option „method“. Diese gibt die Methode an, die du für die HTTP-Anfrage verwendest. Es gibt 5 Methoden, die du verwenden kannst: GET, POST, PUT, PATCH und DELETE, wobei die ersten beiden am häufigsten verwendet werden (GET und POST). Wenn keine Methode angegeben wird, verwendet Node-Fetch standardmäßig GET.
Um eine POST-Anfrage mit Node-Fetch zu stellen, kannst du diesen Code-Schnipsel verwenden:
(async () => {
const response = await fetch('http://httpbin.org/post', {
method: 'POST',
body: JSON.stringify({
'key': 'value'
})
});
const body = await response.text();
console.log(body);
})();Was dir hier vielleicht auffällt, ist, dass wir JSON.stringify verwenden, um den Request-Body zu senden. Das liegt daran, dass die Fetch-API den Body als String statt als Objekt sendet, wie es andere Pakete wie Axios tun.
Die Fetch-API deckt auch alle anderen Anfragemethoden ab.
Fehlerbehandlung in Node-Fetch
Die Fehlerbehandlung bei HTTP-Anfragen ist ein Muss, da man sich nie darauf verlassen kann, dass ein Drittanbieter-Dienst immer verfügbar ist. Als bewährte Vorgehensweise solltest du Fehler immer behandeln, um zu verhindern, dass deine App oder dein Skript zusammen mit der URL, an die du die Anfrage stellst, ausfällt.
Die Fehlerbehandlung in Node-Fetch kann durch Umschließen des Codes mit einer einfachen Try-Catch-Syntax erfolgen. Hier ist ein Beispiel, wie das bei der Verwendung von await funktioniert:
(async () => {
try {
const response = await fetch('[INVALID_URL]');
const responseBody = await response.text();
} catch (error) {
console.log(error.message);
}
})();Wenn du stattdessen lieber „fetch“ ohne „await“ verwenden möchtest, kannst du deinem Code wie folgt ein „catch“ hinzufügen:
fetch('[INVALID_URL]')
.then((response) => response.text())
.then((body) => {
console.log(body);
})
.catch((error) => {
console.log(error.message);
});Anwendungsfälle für Node-Fetch
Das Erstellen von HTTP-Anfragen kann in vielerlei Hinsicht nützlich sein, da es ermöglicht, neue Informationen von verschiedenen Diensten abzurufen und Daten auf recht elegante und einfache Weise zu extrahieren. Es gibt einige Anwendungsfälle hierfür, die wir in den folgenden Abschnitten näher betrachten werden.
Verwenden Sie Node-Fetch für API-Anfragen
Beim Programmieren müssen Sie oft eine API verwenden. Der Grund dafür ist, dass Sie möglicherweise bestimmte Daten aus einer anderen Backend-Quelle abrufen und diese dann verarbeiten oder aktualisieren müssen. Ein gutes Beispiel hierfür wäre eine API mit 4 Endpunkten, die es Ihnen ermöglicht, Benutzer (CRUD-Operationen) in einer Backend-Datenbank von einem anderen Server aus zu erstellen, zu lesen, zu aktualisieren und zu löschen.
Häufig erfordert eine solche API eine Authentifizierung, um zu verhindern, dass unbefugte Quellen sie nutzen und die Daten zu ihrem Vorteil verändern. HTTP-Anfragen bieten viele Methoden zur Authentifizierung. Eine der gängigsten ist die Verwendung eines API-Schlüssels, bei der der API-Anbieter Ihnen einen Schlüssel zur Verfügung stellt, den nur Sie kennen sollten, und die Endpunkte der API funktionieren nur, wenn der richtige Schlüssel gesendet wird.
Eine weitere Methode, mit der eine API geschützt werden kann, ist die Basic-Authentifizierung. Das bedeutet, dass du für den Zugriff auf die API einen Header mit einer Base64-kodierten Zeichenfolge im Format „Benutzername:Passwort“ senden musst. Hier ist ein Beispiel dafür, wie du die Basic-Authentifizierung in einer POST-Anfrage verwenden kannst:
(async () => {
const response = await fetch('http://httpbin.org/post', {
method: 'POST',
headers: {
"Authorization": `Basic ${btoa('login:password')}`
},
body: JSON.stringify({
'key': 'value'
})
});
const body = await response.text();
console.log(body);
})();Verwenden Sie Node-Fetch für Web Scraping
Web-Scraping ist eine Methode, um Inhalte von Websites abzurufen und zu parsen, sodass Sie nur die benötigten Daten behalten, die Sie nach Belieben verwenden können. Eine gute npmjs-Bibliothek, mit der Sie das Parsen der Daten vereinfachen können, ist cheerio. Diese Bibliothek ermöglicht es Ihnen, statisches HTML, sobald es über die Fetch-API abgerufen wurde, genauso abzufragen, wie Sie es über JavaScript oder jQuery tun würden.
Hier ist ein Beispiel dafür, wie Sie den Titel einer Seite mithilfe der Fetch-API und cheerio abrufen können:
const cheerio = require("cheerio");
(async () => {
const response = await fetch('https://www.webscrapingapi.com/');
const responseBody = await response.text();
const $ = cheerio.load(responseBody);
console.log($('title').first().text());
})();Das obige Beispiel sollte „WebScrapingAPI | All-In-One Scraping API“ zurückgeben, da dies der Titel der Seite ist (der Text, der oben im Fenster Ihres Browsers steht). Um es aufzuschlüsseln: Wir verwenden „fetch“, um den HTML-Quellcode der Seite von https://www.webscrapingapi.com/ abzurufen, und wir verwenden „cheerio“, um diesen Inhalt zu parsen. Um mehr über „cheerio“ zu erfahren, können Sie sich die Dokumentation hier ansehen
Das Scrapen von Informationen von anderen Websites kann in vielerlei Hinsicht nützlich sein. Beispielsweise können gescrapte Informationen verwendet werden, um einen Trainingsdatensatz für ein Machine-Learning-Modell zu erstellen oder um ein Preisvergleichstool zu entwickeln, das Daten aus vielen Quellen extrahiert und diese dann vergleicht.
Das obige Beispiel funktioniert zwar einwandfrei, doch die Fetch-API ist beim Scraping möglicherweise nicht immer die beste Option. Das liegt daran, dass moderne Websites ihre Inhalte heutzutage über JavaScript anzeigen und Captchas oder andere Methoden einsetzen, um zu verhindern, dass ihre Daten gescrapt werden. Die Fetch-API funktioniert wie ein einfacher CURL-Aufruf an die angegebene URL und ruft den statischen Inhalt ab, den die Seite beim Laden anzeigt, ohne jegliche JavaScript-Rendering.
Um Daten zu scrapen und gleichzeitig den JavaScript-Code auf der Seite auszuführen, sollten Sie sich Alternativen wie Puppeteer ansehen, wie in diesem Artikel über fortgeschrittenes Scraping beschrieben. Wenn Sie sich diesen ganzen Aufwand jedoch ersparen möchten, können Sie WebScrapingAPI verwenden, eine speziell für diese Aufgabe entwickelte API, die all diese Probleme (einschließlich Anti-Bot-Erkennung) löst und eine kostenlose Testversion mit allen Funktionen bietet.
Zusammenfassung
Zusammenfassend lässt sich sagen, dass die gute Nachricht darin besteht, dass die lang erwartete Fetch-API endlich in Node.js verfügbar ist, auch wenn sie sich derzeit (zum Zeitpunkt der Erstellung dieses Artikels) noch in der experimentellen Phase befindet. Zwar war es schon zuvor möglich, Anfragen in Node.js zu stellen, doch die einzige Möglichkeit bestand darin, entweder die XMLHttpRequest/XHR-Objekte oder eines der vielen verfügbaren Pakete wie Axios oder GOT zu verwenden.
Diese Änderung wird clientseitiges JavaScript und serverseitiges Node.js einander näherbringen, da diese Funktion bereits in clientseitigem JavaScript verfügbar war und von allen modernen Browsern unterstützt wurde.
Das Absenden von HTTP-Anfragen kann in vielerlei Hinsicht nützlich sein, beispielsweise bei der Nutzung einer API oder beim Scrapen von Daten von einer Website. Während die anderen npm-Pakete weiterhin eine Option bleiben und in älteren Projekten weiterhin verwendet werden, ist die Verwendung von fetch die beste Lösung für die Zukunft. Dies wird die Lesbarkeit von Node.js-Code verbessern und den Wechsel vom Frontend zum Backend noch einfacher machen.




