Das globale Tool: fetch()

Mit der eingebauten Funktion fetch() kann JavaScript Daten von einem Server anfordern (z. B. neue Wetterdaten, User-Profile oder Produktlisten nachladen), ohne dass die gesamte Website neu geladen werden muss.

Das passiert asynchron im Hintergrund. Das bedeutet: Während der Server die Daten sucht und schickt, friert die Website nicht ein, sondern der Nutzer kann normal weiterscrollen.

Das Kernkonzept: Promises (Versprechen)

Weil fetch() im Hintergrund arbeitet und Netzwerke manchmal langsam sind, liefert die Funktion nicht sofort die fertigen Daten zurück, sondern ein sogenanntes Promise (ein Versprechen).

Ein Promise sagt: "Ich bin noch nicht fertig, aber ich verspreche dir, dir das Ergebnis (oder eine Fehlermeldung) zu liefern, sobald ich es habe."

Um auf dieses Versprechen zu warten, nutzen wir im modernen JavaScript die Schlüsselwörter async und await.

 

Wichtige Schritte bei jedem fetch()

Wenn wir Daten von einem Server holen (ein sogenannter GET-Request), läuft das fast immer in zwei Schritten ab:

  1. Die Verbindung aufbauen: Wir "fetchen" die URL. Der Server antwortet mit einem Status (z. B. "200 OK"). Die eigentlichen Daten sind hier aber noch im Rohformat (ein Datenstrom).

  2. Die Daten umwandeln: Wir müssen JavaScript sagen, welches Format die Daten haben. Meistens ist das JSON (ein Textformat, das aussieht wie JavaScript-Objekte). Mit .json() wandeln wir den Datenstrom in ein echtes JavaScript-Objekt um.

Beispiel 1: Der Standard-Fall (Daten abrufen mit async/await)

In diesem Beispiel holen wir uns Nutzerdaten von einer JSON-Datei: benutzer.json.

 // Da wir "await" nutzen wollen, muss die Funktion als "async" markiert sein
async function ladeBenutzer() {
    // 1. Die Antwort (Response) vom Server abwarten
    const antwort = await fetch('benutzer.json');
    
    // 2. Den Inhalt in ein lesbares JavaScript-Objekt umwandeln
    const benutzer = await antwort.json();
    
    // 3. Jetzt können wir ganz normal mit den Daten arbeiten
    let output = document.getElementById( "output" );
    output.textContent = `Hallo, mein Name ist ${ benutzer[ 0 ].name }!`;
}

// Funktion aufrufen
ladeBenutzer();
 

Beispiel 2: Fehler abfangen (Sehr wichtig für die Praxis!)

Im Internet kann viel schiefgehen (Server down, Tippfehler in der URL, kein Internet). Hier wird gezeigt, wie man Fehler mit try...catch abfängt, damit die Website nicht abstürzt.
Beispiel2 / benutzer1.json

let output = document.getElementById( "output" );
async function ladeBenutzer ()
{
try
{
  const antwort = await fetch( 'benutzer1.json' );

  // Wichtig: fetch() wirft bei einem 404 (nicht gefunden) keinen Fehler!
  // Wir müssen selbst prüfen, ob die Antwort "ok" war.
  if ( !antwort.ok )
  {
    throw new Error( `Server-Fehler: Status ${ antwort.status }` );
  }

  const daten = await antwort.json();
  output.textContent = `Mein Name ist ${ daten.name } ich wohne in ${ daten.adresse.stadt }`;

} catch ( fehler )
{
  // Hier landet JavaScript, wenn das Internet weg ist oder "throw" ausgelöst wurde
  output.textContent = "Upps, da ging etwas schief:", fehler.message;
}
}
ladeBenutzer();

Wer erstellt das ok?

Wenn du const antwort = await fetch(...) ausführst, lädst du nicht nur die Datei herunter. Der Browser erstellt im Hintergrund ein großes JavaScript-Objekt (das Response-Objekt).

In dieses Objekt schreibt der Browser Metadaten über die Verbindung zum Server. Eine dieser fest eingebauten Eigenschaften ist ok.

Der Gegenbeweis: Wie sieht das antwort-Objekt wirklich aus?

Stell dir vor, du fragst eine Datei ab, die es gar nicht gibt (z.B. fetch('gibts-nicht.json')). Der Server schickt dir also gar keine Datei und somit auch kein JSON.

Trotzdem existiert das antwort-Objekt! Wenn man es unter die Lupe nehmen würde, sähe es im JavaScript-Speicher ungefähr so aus:

// Das ist das unsichtbare Response-Objekt, das der Browser für dich baut:
{
  status: 404,
  statusText: "Not Found",
  ok: false,              // <-- Hier ist das 'ok'! Automatisch auf false gesetzt.
  url: "https://api.beispiel.de/gibts-nicht.json",
  headers: { ... },
  
  // Hier drin würde der unlesbare Datenstrom liegen, 
  // aber da es die Datei nicht gibt, ist er leer:
  body: ReadableStream 
}

Warum ist das wichtig?

Du nutzt antwort.ok, bevor du überhaupt versuchst, die JSON-Datei mit .json() auszupacken.

Das ist die Sicherheitskontrolle:

 const antwort = await fetch('benutzer1.json');

// Wir schauen NUR auf die Verbindung (die Metadaten des Browsers):
if (!antwort.ok) {
    // Wenn antwort.ok false ist, brechen wir ab. 
    // Wir versuchen erst gar nicht, die Datei auszupacken, weil sie fehlerhaft ist!
    throw new Error("Datei konnte nicht geladen werden"); 
}

// Erst WENN antwort.ok true ist, lesen wir den Inhalt der Datei:
const daten = await antwort.json();
 

 

Beispiel 3: Daten an einen Server senden (POST-Request)

fetch() kann nicht nur Daten holen, sondern auch Daten senden (z. B. wenn ein Nutzer ein Formular abschickt). Dafür übergeben wir fetch() ein zweites Argument: ein Konfigurationsobjekt.

async function neuerBenutzer(name, beruf) {
    const daten = { name: name, job: beruf };

    const antwort = await fetch('https://api.beispiel.de/users', {
        method: 'POST', // Wir sagen: Wir wollen Daten senden!
        headers: {
            'Content-Type': 'application/json' // Wir sagen dem Server, dass wir JSON senden
        },
        body: JSON.stringify(daten) // Wir machen aus dem JS-Objekt einen JSON-String
    });

    const ergebnis = await antwort.json();
    console.log('Erfolgreich gesendet:');
}

⚠️ Wichtiger Hinweis für die Praxis: > Mit fetch() und POST senden wir Daten an ein Tor (die Server-Schnittstelle / API). Ob der Server diese Daten dann wirklich in einer Datei oder Datenbank abspeichert, liegt ganz in der Hand des Servers (Backend). Ein normaler Browser-Code (Frontend) kann niemals direkt Dateien auf einem Server oder der Festplatte des Nutzers verändern.

Beispiele 4: Daten aus einer öffentlich zugängichen JSON Datei laden

Es gibt öffentlich zugängliche JSON-Dateien die Informationen zu verschiedenen Themenbereichen zur Verfügung stellen. Daten zu Staaten gibt es unter https://raw.githubusercontent.com/mledoze/countries/master/countries.json
Hier wird mit 3 Beispielen Schritt für Schritt eine interaktive Webanwendung erstellt. In der letzten Version kann man einen Staat wählen, um die Basisdaten des Staates zu erfahren.

  1. 04a-fetch.html Die JSON Datei wird geladen und die Informationen von Kanada angzeigt
  2. 04b-fetch.html Auf Button-Click werden die Infos von Kanada angezeigt
  3. 04c-fetch.html Durch Select-Auswahl werden die Informationen des gewählten Landes angezeigt

Beispiele 5: Daten von restcountries

Restcountries liefert Länderdaten. Man muss sich anmelden und bekommt einen persönlichen API Key. Damit kann man Daten herunterladen, jedoch nicht im Browser, sonder mit node.js, damit nicht jeder den Api-Schlüssel stehlen.

Um die Daten im Netz zu nutzen, kann man die Daten in eine eigene JSON-Datei speichern. mehr dazu hier

In diesem Beispiel werden einige Daten ausgegeben.