Daten im Hintergrund laden statt neu zu laden
Bei der klassischen Webanwendung (z.B. bei einer Anfrage an ein PHP-Skript) lösen Aktionen des Benutzers einen HTTP-Request zurück zum Server aus.
Das PHP-Script verifiziert den Benutzer, liest Daten aus der Datenbank, berechnet ein paar Zahlen und liefert dann eine neue HTML-Seite an den Client aus. Dabei besteht die neue Seite zum größten Teil aus denselben Elementen wie vorher und nur wenige Inhalte wurden tatsächlich geändert.
XMLHttpRequest: Datei com Server laden
XHR ist eine Schnittstelle zwischen Javascript und den Daten auf dem Server. Im einfachsten Fall holt Javascript Daten aus einer XML- oder JSON-Datei vom Server – ohne Beteiligung einer serverseitigen Anwendung.
Der Name XMLHttpRequest ist etwas irreführend, denn der XMLHttpRequest unterstützt nicht nur XML, sondern alle textbasierten Formate, und sowohl Requests als Antworten (Response).
Alles, was Javascript braucht, um eine JSON-Datei vom Server zu laden, ist ein HTML-Element für die Daten.
<ul id="products"></ul>
Die JSON-Datei enthält ein Array von Objekten, die wiederum die Informen zu drei Bildern enthalten.
[ {"src": "lampe-01.webp", "width": 531, "height": 509, "alt": "Lampe »Munkola«"}, {"src": "lampe-02.webp", "width": 531, "height": 509, "alt": "Lampe »Mirmis«"}, {"src": "lampe-03.webp", "width": 531, "height": 509, "alt": "Lampe »Jolii«"} ]
Als erste Aktion initialisiert das Skript einen XMLHttpRequest und ruft open () auf. open () braucht zwei Argument: die Art des Requests und die URL der JSON-Datei auf dem Server.
const xhr = new XMLHttpRequest (); xhr.open ("GET", "products.json"); xhr.onreadystatechange = function () { console.log (this.readyState) } xhr.send ();
Ein Event Handler wartet auf das Eintreffen eines readystatechange-Events. readystatechange kommt mit einem von fünf möglichen Werten:
- Request wurde nicht initialisiert
- Verbindung zum Server ist aufgebaut
- Request erhalten
- Request wird ausgeführt
- Request beendet und die Antwort steht bereit
Am Ende sendet xhr.send () den Request. Schön zu sehen: Die Rückgabewerte geben den Ablauf des Requests wieder.
2
3
4
Wir interessieren uns nur für den Wert 4 und den Status-Code 200 (Request erfolgreich). this.readyState und this.status sind auch die Werte, die Hinweise geben, wenn der Request nicht ausgeführt wird.
Um die Daten in die Webseite zu setzen, holt forEach () die Informationen zu jedem der drei Objekte innerhalb der if-Abfrage.
if (this.readyState === 4 && this.status === 200) {
const data = JSON.parse (this.responseText);
data.forEach (item => {
const li = document.createElement ("li");
const img = document.createElement ("img");
img.src = item.src;
li.append (img);
document.querySelector ("#producs").append (li);
});
}
XMLHttpRequest für ein API
Im Grunde genommen funktioniert das Einholen von Informationen aus einer Anwendung auf einer anderen Webseite über ein API (Application Programming Interface) kaum anders aus
Viele Anwendungen stellen Programmierschnittstellen zur Verfügung, an denen sie Daten für andere Webseiten oder Anwendungen anbieten. Das Spektrum reicht von Wetterdaten über Straßenkarten (z.B. Openstreetmap auf https://wiki.openstreetmap.org/wiki/API) und den APIs der Social Media bis hin zu Github-Benutzern und -Projekten. Generell bestehen APIs aus Befehlen, Funktionen, Protokollen und Objekten. Jedoch unterscheidet sich die Form von Anbieter zu Anbieter: Ein API ist kein Heimspiel wie die JSON-Datei auf dem eigenen Webspace.
openthesaurus.de ist ein Projekt im Internet, mit dem Autoren nach Synonymen und Assoziationen für einen Begriff suchen können. Das API von openthesaurus.de bietet wahlweise XML- oder JSON als Austauschformat.
<input id="thesaurus" value="Türöffner" type="text" placeholder="Gib mir ein Wort!"/> <button id="btn">Suche</button> <ul id="alt"></ul>
Die Variable word enthält den Begriff, für den ein Ersatz gesucht wird.
const button = document.querySelector ("#btn"); const xhr = new XMLHttpRequest (); button.addEventListener ("click", function () { const xhr = new XMLHttpRequest (); const thesaurus = document.querySelector ("#thesaurus"); const word = encodeURI(thesaurus.value); const url = `https://www.openthesaurus.de/synonyme/search?q=${word}&format=application/json`; xhr.open ("GET", url); xhr.onreadystatechange = function () { if (this.readyState === 4 && this.status === 200) { const data = JSON.parse (this.responseText); console.log (data); resolve (data); } } xhr.send (); });
Die Ausgabe der JSON-Daten in der Konsole des Browsers zeigt die Struktur der gewünschten Informationen. Die Struktur der Daten eines APIs ist immer wieder eine andere und muss aufgeschlüsselt werden.
▼ synsets: Array (2)
▶ 0 {id: 37879, categories: [], terms: [{term: "ein Anfang (sein)"}, … ]}
▶ 1 {id: 43686, categories: [], terms: [{term: "Türen öffnen"}, … ]}
Die Funktion resolve löst die gelieferten Objekte auf und überträgt sie in die Liste.
function resolve (data) { data.synsets.forEach (item => { item.terms.forEach ( e => { const li = document.createElement ("li"); li.innerHTML = e.term; document.querySelector ("#alt").append (li) } ) }); }
IE11 Unterstützung XHR ? XHR open() und send()
Wenn IE11 noch unter den Hut gebracht werden muss, geht die Zeitreise zurück in die Vergangenheit. Die gebräuchlichste Anweisungssequenz für einen XMLHttpRequest bestand früher aus
- dem Erzeugen einer Instanz des XMLHttpRequest-Objekts let xhr = new XMLHttpRequest(),
- Aufruf der open()-Methode,
- Abfragen von onreadystatechange und Aufruf einer Funktion, die beim Eintreffen der Antwort die Verarbeitung übernimmt.
- Senden des Requests mit der send()-Methode
let xhr = new XMLHttpRequest(); // Methode Datei asynchron xhr.open ( "GET", "books.xml", true ); xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200) { //console.log (xhr.responseText); document.querySelector(".listxmp").innerHTML = xhr.responseText; } } xhr.send ();
xmlObj.open sendet den GET-Request (nur Daten holen) an den Server. Für die Verarbeitung von Formulardaten wird POST benutzt. Dann wäre der erste Parameter von xhr.open ein POST, und der Parameter von xhr.send wären die Daten, die an den Server gesendet würden.
Der dritte Parameter steht für async = true. Der Request wird asynchron (quasi gleichzeitig) ausgeführt und blockiert die Seite nicht.
Wann liegt die Antwort auf den Request vor? xhr.onreadystatechange muss vor dem Senden des Requests mit xhr.send() aufgerufen werden.
onreadystatechange gibt den Ablauf der Abfrage zurück und durchläuft die Werte 0 bis 4. onreadystatechange feuert bis zur Antwort "4" ununterbrochen den Status der Abfrage. Heute können wir anstelle von xhr.onreadystatechange xhr.onload nutzen. onload meldet sich nur, wenn der Request erfolgreich durchgeführt wurde.
xhr.responseText ist ein XMLHttpRequest-Objekt, dessen Methoden alle Operationen steuern und dessen Eigenschaften die Daten speichern, die der Server zurückgeliefert.
readystatechange ist das Event, dass alle Antworten abfängt. Ursprünglich war readystatechange das einzige Ereignis des XMLHttpRequest, aber mit XMLHttpRequest Version 2 sind weitere Events wie XHR onload und onerror hinzugekommen.
Prüfen, ob ein Bild oder ein Link existiert
(function(){ let xhr = new XMLHttpRequest(); xhr.open('HEAD', "xmlhttp.png", true); xhr.send(); if (xhr.status == "404") { console.log ("Gibts nicht"); return false; } else { console.log ("Alles OK xmlhttp.png gibt es"); return true; } })();