JavaScript/XMLHttpRequest
Das XMLHttpRequest-Objekt wird zum Austausch von Daten zwischen Nutzer und Server verwendet. Man kann damit ...
- eine Webseite aktualisieren, ohne sie neu laden zu müssen
- Daten vom Server anfordern, nachdem die Seite geladen ist
- Daten zu einem Server im Hintergrund senden
Eigenschaften
XMLHttpRequest.timeout
XMLHttpRequest.withCredentials
XMLHttpRequest.upload
XMLHttpRequest.status
XMLHttpRequest.statusText
XMLHttpRequest.readyState
XMLHttpRequest.response
XMLHttpRequest.responseText
XMLHttpRequest.responseType
XMLHttpRequest.responseXML
Methoden
XMLHttpRequest.open()
XMLHttpRequest.setRequestHeader()
XMLHttpRequest.send()
XMLHttpRequest.abort()
XMLHttpRequest.getResponseHeader()
XMLHttpRequest.getAllResponseHeaders()
XMLHttpRequest.overrideMimeType()
Events
-
readystatechange
wenn sich der Status geändert hat -
loadstart
: Anfrage wurde gestartet. -
progress
: Daten werden gesendet oder empfangen. -
abort
: Anfrage wurde abgebrochen (z.B. durchabort()
) -
error
: Anfrage ist gescheitert. -
load
: Anfrage wurde erfolgreich abgeschlossen -
: Timeout-Zeit wurde überschritten (obsolet)timeout
-
loadend
: Anfrage wurde beendet (egal ob erfolgreich oder gescheitert)
Inhaltsverzeichnis
Anwendung
Beispiel 1: Verwendung
Das Ajax-Objekt mit Daten füttern
var request = new XMLHttpRequest();
request.open("GET","daten.txt");
request.setRequestHeader("X-Test","test1");
request.setRequestHeader("X-Test","test2");
Als erstes erstellen wir ein neues Anfrage-Objekt. Anschließend füttern wir es mit der verwendeten HTTP-Methode und der URL, die wir anfragen möchten. Danach setzen wir noch beispielhaft einen Anfrage-Header. Wenn man nun zwei mal den gleichen Anfrage-Header (wie im Beispiel) angibt, kombiniert das Anfrage-Objekt beide Werte.
Die Verarbeitung bestimmen
request.addEventListener('load', function(event) {
if (request.status >= 200 && request.status < 300) {
console.log(request.responseText);
} else {
console.warn(request.statusText, request.responseText);
}
});
Unsere Verarbeitung ist recht simpel: Wenn nichts schief gelaufen ist, lassen wir uns den Inhalt der angeforderten Ressource in der Konsole ausgeben. Im Fehlerfall geben wir darüber hinaus den HTTP-Fehlercode aus und schreiben ihn als Warnung in die Konsole. Ein HTTP-Statuscode im Bereich 200-299 bedeutet, dass die serverseitige Bearbeitung erfolgreich war. responseText
beinhaltet den Inhalt der Serverantwort.
Die Anfrage senden
request.send();
Die Anfrage wird gesendet. Wenn die Anfrage Daten an den Server übertragen soll, werden diese als Parameter der send-Methode übergeben (siehe dazu das zweite Beispiel).
Kompletter Code
var request = new XMLHttpRequest();
request.open("GET","daten.txt");
request.setRequestHeader("X-Test","test1");
request.setRequestHeader("X-Test","test2");
request.addEventListener('load', function(event) {
if (request.status >= 200 && request.status < 300) {
console.log(request.responseText);
} else {
console.warn(request.statusText, request.responseText);
}
});
request.send();
Beispiel 2: Benutzernamen-Prüfung
Hier wird nun das bereits erwähnte Beispiel mit Code hinterlegt.
Was wird gebraucht?
- Ein serverseitiges Skript zur Überprüfung des gewünschten Benutzernamens
- Eine HTML-Seite mit Formular
- Das eigentliche JavaScript
Des Weiteren wird davon ausgegangen, das sich alle Dateien im gleichen Verzeichnis auf dem Webserver befinden.
serverseitige Überprüfung
Für das Beispiel wird PHP verwendet. Genannt wird die Datei "usernamecheck.php".
<?php
$responseStatus = '200 OK';
$responseText = '';
if(!isset($_POST['username'])) {
$responseStatus = '400 Bad Request';
$responseText = 'Anfrage erhält keinen Nutzernamen';
} else {
$usernames = array('admin','gast','paul');
$validatePattern = '/^[a-z0-9]{4,20}$/';
if(in_array($_POST['username'],$usernames)) {
$responseStatus = '409 Conflict';
$responseText = 'Nutzername bereits in Verwendung';
} elseif(!preg_match($validatePattern,$_POST['username'])) {
$responseStatus = '400 Bad Request';
$responseText = 'Nutzername entspricht nicht den Vorgaben. Der Benutzername muss aus kleinen Buchstaben(a-z) und/oder Ziffern(0-9) bestehen und 4-20 Zeichen lang sein';
} else {
$reponseStatus = '204 No Content';
}
}
header($_SERVER['SERVER_PROTOCOL'].' '.$responseStatus);
header('Content-type: text/html; charset=utf-8');
echo $responseText;
Das Script erwartet den Benutzernamen via POST-Methode und unter dem Namen username
.
Im Erfolgsfall antwortet es mit dem HTTP-Status "204 No Content". Im Fehlerfall setzt es den entsprechenden HTTP-Fehlerstatus und schreibt eine ausführlichere Fehlermeldung in die Server-Antwort.
HTML-Seite
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<title>Benutzerüberprüfung</title>
<script src="check.js" defer></script>
</head>
<body>
<form method="POST" action="usernamecheck.php">
<label for="username">Benutzername</label>
<input id="username" name="username" pattern="^[a-z0-9]{4,20}$">
<p>Der Benutzername muss aus kleinen Buchstaben(a-z) oder Ziffern(0-9) bestehen
und 4-20 Zeichen lang sein"</p>
<button>Prüfe</button>
</form>
</body>
</html>
JavaScript-Datei
Dateiname: check.js
var form = document.querySelector('form');
form.addEventListener('submit', function (event) {
event.preventDefault();
var data = new FormData(form);
check(data);
});
function check (data){
var request = new XMLHttpRequest();
request.addEventListener('load', function(event) {
if (request.status >= 200 && request.status < 300) {
console.log(request.responseText);
} else {
console.warn(request.statusText, request.responseText);
}
});
request.open("POST","usernamecheck.php");
request.send(data);
}
Der EventListener muss vor der Methode .send() stehen. Statt addEventListener() kann man die Funktion auch direkt an .onreadystatechange= zuweisen. Diese wird für diverse Zwischenstufen (1-4, beim alten Opera 12 nicht alle) aufgerufen.
Es ist zu beachten, dass das Beispiel bei weitem nicht vollständig ist. In einer echten Anwendung, müssten wir zumindest noch dem Anwender ein Feedback darüber erteilen, wie unsere serverseitige Prüfung von statten gegangen ist. Außerdem ist es wahrscheinlich, dass wir das Formular noch robuster gestalten möchten, indem wir auch die Ereignisse "error" und "abort" des Anfrage-Objekts entsprechend behandeln.
Geschichte
Ursprung
Die XMLHttpRequest-Technik wurde ursprünglich von Microsoft als ActiveX-Objekt für den Internet Explorer 5 entwickelt und von anderen Browsern übernommen. Allerdings waren diese verschiedenen XMLHttpRequest-Implementierungen nicht vollständig zueinander kompatibel. Aus diesem Grund wurde im Dezember 2012 eine einheitliche Definition für das XMLHttpRequest-Objekt durch das W3C zur Standardisierung vorgeschlagen.[W3C 1]. Mittlerweile (17.01.2018) bezeichnet das W3C dieses Dokument als „discontinued“ und verweist auf den Living Standard der WhatWG[WhatWG 1].
var ajax = null;
if(window.XMLHttpRequest){ //Google Chrome, Mozilla Firefox, Opera, Safari, IE 7
ajax = new XMLHttpRequest();
}
else if(window.ActiveXObject){ // Internet Explorer 6 und niedriger
try{
ajax = new ActiveXObject("Msxml2.XMLHTTP.6.0");
} catch(e){
try{
ajax = new ActiveXObject("Msxml2.XMLHTTP.3.0");
}
catch(e){}
}
}
if(ajax==null)
alert("Ihr Browser unterstützt kein Ajax!");
XMLHttpRequest 2
Eine erweiterte Spezifikation von XMLHttpRequest, in der domainübergreifende Abfragen und die Unterstützung von Datenströmen geplant sind, hat beim W3C seit Januar 2012 den Status eines Arbeitsentwurfs.[W3C 2]. Mittlerweile ist dieser Entwurf ebenfalls als „discontinued“ klassifiziert und leitet zum Living Standard der WhatWG[WhatWG 1] weiter.
Ausblick
Neben der noch nicht abgeschlossenen Entwicklung von XHR2 wurde mit der window.fetch
-Methode eine API als bequeme und zeitgemäße Alternative eingeführt, die das Handling von JSON-Dateien künftig erleichtern wird.
Quellen
- ↑ 1,0 1,1 WhatWG: XMLHttpRequest
ajax
mitnull
initialisiert, als nächstes wird getestet ob dasXMLHttpRequest
-Objekt (Ajax) existiert und ggf. erzeugt. Falls nicht (bei älteren Internet Explorer Versionen) wird das jeweilige ActiveX-Objekt abgefragt, und am Ende, für den Fall, dass dasajax
-Objekt immer nochnull
ist, eine Fehlermeldung ausgegeben.