diff --git a/src/components/slides/javascript/08-data-fetching/fetch-demo.astro b/src/components/slides/javascript/08-data-fetching/fetch-demo.astro new file mode 100644 index 0000000..292fb86 --- /dev/null +++ b/src/components/slides/javascript/08-data-fetching/fetch-demo.astro @@ -0,0 +1,32 @@ +--- +interface Props { + url: string, + id: string, + converter: 'text', +} + +const { url, id, converter } = Astro.props; +--- + +
Headers sind dafür zuständig zusätzliche Informationen vom und zum Server zu übertragen.
+Diese Informationen sind unter anderem: Authentifizierungs und Authentifikations-Informationen, Caching-Informationen, Content-Flags, Cookies, Cross-Origin-Resource-Sharing-Informationen, und viele weitere.
+Eine Umfangreiche Liste ist zu finden auf Developer Mozilla
+Header sind eine spezielle Klasse die initiiert werden kann.
+
+ const headers = new Headers();
+
+ // Header können folgendermaßen in
+ // einem Request verwendet werden
+ const response = await fetch('url', {
+ headers,
+ });
+
+ Die Header-Instanz enthält folgende Funktionen um Header zu modifizieren:
+headers.append(name, value)
+Fügt einen neuen Header-Eintrag zum Objekt hinzu
+headers.delete(name)
+Entfernt einen Eintrag aus dem Header
+headers.get(name)
+Gibt einen String zurück der den Inhalt des Angegebenen Header-Eintrages abbildet. null
wenn kein Eintrag vorhanden ist.
headers.has(name)
+Prüft ob ein Header-Eintrag mit gegebenen Namen existiert, falls ja liefert die Funktion true
, andernfalls false
.
headers.set(name, value)
+Setzt einen Eintrag im Header-Objekt mit angegebenem Wert, überschreibt existierende Werte.
+Zum Anhängen an einen existierenden Wert, kann man die Funktion .append()
nutzen
"Jason", oder auch "JavaScript Object Notation"
+JSON ist ein modernes Datenformat um strukturierte Daten zu übertragen.
+Der Inhalt ist dabei stark den JavaScript-Objekten nachempfunden
+
+ {
+ "days_until":38,
+ "following_production": {
+ "days_until":58,
+ "id":202555,
+ "overview":"Matt Murdock, a blind lawyer with heightened abilities, is fighting for justice through his bustling law firm, while former mob boss Wilson Fisk pursues his own political endeavors in New York. When their past identities begin to emerge, both men find themselves on an inevitable collision course.",
+ "poster_url":"https://image.tmdb.org/t/p/w500/bSsjWM91kSZqW0BagqaoIeo8Jz7.jpg",
+ "release_date":"2025-03-04",
+ "title":"Daredevil: Born Again",
+ "type":"TV Show"
+ },
+ "id":822119,
+ "overview":"After meeting with newly elected U.S. President Thaddeus Ross, Sam finds himself in the middle of an international incident. He must discover the reason behind a nefarious global plot before the true mastermind has the entire world seeing red.",
+ "poster_url":"https://image.tmdb.org/t/p/w500/z0ujnXounP4yq637zyLBiZThF7Y.jpg",
+ "release_date":"2025-02-12",
+ "title":"Captain America: Brave New World",
+ "type":"Movie"
+ }
+
+ Es sind alle Gängigen JavaScript Datentypen erlaubt, inklusive null
und undefined
.
Es gibt per-se keine Feste Datenstruktur, die vorgibt welche keys erlaubt sind und welche nicht. Wir können das Datenformat entsprechend dynamisch gestalten.
+Es gibt aber darauf aufbauend das JSON-Schema, mit dem ein Parser eine "wohlgeformte" JSON-Struktur identifizieren kann.
+JSON-Schema ist aber nicht teil dieser Vorlesung.
+"Vorgänger" von JSON ist / war SOAP. SOAP war XML-Basiert und wurde früher in großem Umfang von vielen Systemen benutzt. Aufgrund des Aufwandes ist aber JSON nun der de-facto Standard bei Datenübertragungen.
+Alle modernen Programmiersprachen bieten Optionen, JSON in Strukturierte Klassen zu parsen.
+Und selbst in JavaScript müssen wir "rohes" JSON in geparste Objekte übersetzten.
+Hierfür steht uns das globale Objekt JSON
mit den Funktionen stringify & parse
zur Verfügung
+ const myObject = { value: 42 };
+
+ const asString = JSON.stringify(myObject);
+
+ console.log(asString);
+
+ const parsed = JSON.parse(asString);
+
+ console.log(parsed);
+
+ Ein Disclaimer: Wir werden im Rahmen der Vorlesung mit der moderneren fetch
API arbeiten. Die Fetch-API hat XMLHttpRequest
abgelöst und bietet moderne Features.
Anatomie eines Fetch-Aufrufs
+Zu Demonstrations-Zwecken nutzen wir eine offene API, die wir ansteuern können:
+
+ // Eine offene API zum abfragen einfacher Wetter-Daten
+ const url = 'https://wttr.in/Karlsruhe?format=4';
+
+ // Fetch gibt uns ein Promise
+ // erfolgreich wenn Request erfolgreich
+ const response = await fetch(url);
+
+ // als letzter schritt holen wir die daten mittels .text()
+ console.log(await response.text());
+
+
+ Wenn wir nichts weiter als die URL angeben, wird ein GET
Request ausgeführt.
Die verschiedenen Request-Formate haben wir bereits betrachtet.
+Weiterhin können wir erkennen, dass ein fetch-Aufruf ein Promise zurück gibt, dass wir await
'en müsen
Wenn wir z.B. POST Requests machen wollen, müssen wir zusätzliche Optionen als 2. Parameter mitgeben
+
+ fetch("url", {
+ method: "POST", // "PUT", "DELETE"
+ body: "Inhalt",
+ });
+
+ Wir haben unseren Request abgeschickt und haben eine Antwort erhalten.
+In den Folien vorher haben wir auch die Antwort bereits extrahiert und angezeigt.
+Bisher haben wir aber nur die Funktion await response.text()
verwendet. Sie liefert den Inhalt der Antwort als normalen String zurück.
Falls es euch damals aufgefallen ist, haben wir beim Empfang des Inhalts mittels .text()
die Antwort mit await
abwarten mussten.
Die Funktion liefert also ein Promise das mit dem Inhalt der Antwort des Requests zurück kommt.
+Aber warum?
+Das liegt daran wie die Datenübertragung funktioniert.
+In dem Moment in dem der Request-Promise "erfüllt" ist, haben wir zwangsweise noch keine Daten erhalten.
+Die Daten vom Body werden als Stream gespeichert. Solange die Datenübertragung noch nicht abgeschlossen ist wird der Stream weiter gefüllt.
+Die Abfrage der Inhalte vom Body mittels .text()
erwartet also, dass der Stream vollständig ist.
Blicken wir aber noch genauer auf den Zustand zwischen dem Request Promise und dem Aufruf um Inhalte zu erhalten.
+Wenn wir vom Server eine Antwort erhalten, kommen die Header zuerst im Browser an.
+Im Header stehen alle für den Request Relevanten Meta-Informationen.
+Unter anderem ist dort auch der HTTP-Status-Code enthalten, mit dem wir den Erfolg des Requests bestimmen können.
+HTTP-Statuscodes sind eine 3-Stellige Nummer zwischen 100 und 599.
+Jede Nummer steht für eine andere Art von Antwort. Grob Kategorisiert werden diese im Hunderter-Bereich:
+Die am gebräuchlichsten Antworten sind:
+200 > OK, 201 > Created, 204 > No Content, 301 > Moved Permanently, 304 > Not Modified, 400 > Bad Request, 401 > Unauthorized, 403 > Forbidden, 404 > Not Found, 500 > Internal Server Error
+Für eine komplette Liste, kann man das Internet fragen, z.B. HTTP Cats
+Zurück zur Response: Wir erhalten also in den Headern bereits den Erfolg oder Miserfolg des Requests, bevor die Daten angekommen sind.
+Entsprechend wird der Request-Promise fullfiled, bevor die Daten komplett angekommen sind.
+Deswegen ist .text()
ein Promise, wir warten noch auf die Vollständigkeit der Daten.
Das Response Objekt hat aber noch weitere Informationen und Funktionen.
+response.headers
+In der headers-property sind alle in der Response beinhalteten Header aufgelistet.
+response.ok
+true
, wenn der HTTP-Statuscode im Bereich 200 bis 299 liegt.
response.status
+Der HTTP-Statuscode den der Server übermittelt hat.
+response.statusText
+Eine Beschreibung des Response-Codes (z.B. OK für 200)
+response.text() (Promise)
+Extrahiert die Antwort des Servers als "Plain-Text"
+response.json() (Promise)
+Extrahiert die Antwort des Servers als JSON-Struktur und parsed die sofort in ein JavaScript-Objekt um.
+Weitere Extraktoren:
+