CSS, HTML und Javascript mit {stil}

XMLHttpRequest open, send

XMLHttpRequest Methoden, Eigenschaften und Events

Die wichtigsten Methoden des XMLHttpRequest-Objekts öffnen die Verbindung zum Server und senden den Request.

Eigentlich klingt es doch ganz einfach: Das Script braucht eine Resource (z.B. ein Bild oder einen Datensatz). Dafür sendet das Script einen Request und die Daten werden in der Response geliefert.

Teil 1: Grundlagen und Beispiele: XMLHttpRequest

Methoden

abort()
Beendet den aktuellen Request
getAllResponseHeaders()
Gibt den vollständigen Header (Label und Werte) als String zurück. Die Namen-/Wertpaare sind durch Carriage Return/Linefeed-Zeichen voneinander getrennt.
getResponseHeader("headerLabel")
Gibt den String-Wert eines einzelnen Header-Labels zurück
open("method", "URL"[, asyncFlag[, "userName"[, "password"]]])
Legt die Ziel-Url, die Methode und weitere optionale Attribute des anstehenden Requests fest
send(content)
Übermittelt den Request, optional mit einem String oder DOM-Objekt-Daten
setRequestHeader("label", "value")
Weist dem Header ein Label/Wert-Paar zu, das mit dem Request versendet wird

Eigenschaften

onreadystatechange
wird bei jeder Änderung des XHR-Zustands aufgerufen
readyState
zeigt grob den Fortschritt während des Requests an.

    XMLHttpRequest erzeugt, aber open() noch nicht aufgerufen, liefert 0.

  • Signal beim erfolgreichen Eröffnen des XHR ist 1 (OPENED).
  • Signal beim erfolgreichen Eröffnen des XHR ist 1 (OPENED).
  • Signal nach dem Senden und Empfang des Response Headers ist 2 (HEADERS_RECEIVED).
  • Daten werden geladen (LOADING).
  • Das entscheidende Signal beim Beenden der Transaktion ist 4 (DONE).
responseType
ArrayBuffer, Blob, Document, JavaScript JSON-Objekt oder String
response
Je nach gesetztem responseType: ArrayBuffer, Blob, Document, JavaScript JSON-Objekt oder String
responseText
String mit Daten, die vom Server zurück gegeben werden
responseXML
DOM-kompatibles Document-Objekt mit Daten, die vom Server geliefert werden
status
Ein numerischer Code, der vom Server zurückgegeben wird, so wie 404 für "Not Found" oder 200 für "OK"
statusText
Eine Nachricht als String, die den Statuscode begleitet
timeout
upload
withCredentials

Events des XMLHttpRequest

Der ursprüngliche XHR kannte nur onreadystatechange, das alle Antworten behandelt. Mit der Version 2 des XMLHttpRequest sind Events hingekommen (inzwischen wurden XMLHttpRequest 1 und XMLHttpRequest 2 zusammengeführt).

readystatechange
löst bei jeder Änderung des readyState aus
loadstart
Beim Starten des Requests
progress
Während Daten gesendet bzw. geladen werden
error
Wenn der Request fehlschlägt
load
Wenn der Request erfolgreich durchgeführt wurde
timeout
Wenn eine vom Script vorgegebene Zeit abläuft, bevor der Request beantwortet wird
loadend
Wenn der Request durchgeführt wurde – entweder erfolgreich oder mit einem Fehler

XHR open()

request.open(method, url, asnc, user, passwword);

Die beiden erforderlichen Parameter der open()-Methode sind die HTTP-Methode und die URL für die Verbindung.

  • GET ist angebracht, wenn es sich im Wesentlichen um eine einfache Anfrage von Daten handelt,
  • POST wird benutzt, wenn die Länge der ausgesendeten Daten größer als 512 Bytes ist.
  • Die URL kann eine vollständige oder relative URL sein.

async ist ein boolescher Wert und legt festlegt, ob die Transaktion asynchron oder synchron durchgeführt werden soll.

  • Die Voreinstellung ist true für einen asynchronen Request: Die Ausführung des Skripts wird sofort nach dem Absetzen der send()-Methode fortgesetzt – ohne auf die Antwort zu warten.
  • Wird der Wert auf false gesetzt, »steht« das Skript und wartet, bis der Request gesendet und die Antwort vom Server angekommen ist. Das ist z.B. das Vorgehen, wenn Benutzername und Passwort geprüft werden müssen.

Ein asynchroner Request ist sicherer und der Normalfall.

XHR send()

Im Workflow des XMLHttpRequest muss zuerst das XMLHttpRequest-Objekt durch open() initialisiert werden. Im nächsten Schritt werden die Request Headers mitsetRequestHeader gesetzt und am Ende wird send() aufgerufen. Die Event Listener sollten registriert sein, bevor send() aufgerufen wird.

send() sendet einen Request an den Server (bei GET). send(string) sendet einen Request an den Server (bei POST)

var xml = "<xml><query><autor>Hergé</autor></query></xml>";
xmlhttp.send(xml);
var xhr = new XMLHttpRequest();
xhr.open( 'post', 'formdata.php', true );

xhr.onload () {
}

xhr.send(data);

oder Übertragung von FormData mit Schlüssel-Wertpaaren an

var form = new FormData();
form.append("member", "Heinz");

var formXHR = new XMLHttpRequest();
formXHR.open("POST", "getfile.php");
formXHR.send(form);

FormData ist nicht auf das Senden von Strings begrenzt, sondern kann auch Files und Blobs versenden.

XMLHttpRequest.responseText

Der Zugriff auf die Daten, die der Server zurückliefert, erfolgt über xhr.responseText, xhr.responseXML oder xhr.response.

responseText
Antwort als Text
responseXML
Objekt wird als vollwertiger XML-Knoten des DOM geparst
response
je nachdem, was als responseType gesetzt wurde: ArrayBuffer, Blob, Document, geparst als vollwertiges JavaScript JSON-Objekt oder einfach als String.

Eine Antwort kann z.B. mit XMLHttpRequest.responseText via onreadystatechange empfangen werden, wenn readyState == DONE.

var xhr = new XMLHttpRequest();
   xhr.open ('GET', "xml-data.xml", true);
   xhr.onreadystatechange = function() {
      if(xhr.readyState == 'DONE') {
         console.log (xhr.responseXML);
      }
   }
   xhr.send ('');

oder als JSON-Objekt beim onload-Event:

var xhr2 = new XMLHttpRequest();
xhr2.open("GET", "autor.json", true);
xhr2.responseType = "json";

xhr2.onload = function (e) {
   var obj = xhr2.response;
} 
xhr2.send();

Die Daten, die vom Server zurück geschickt werden, müssen mit einem Content-Type text/xml geliefert werden. Inhalte, die als text/plain oder text/html gesendet werden, werden von der Instanz des Request-Objekts akzeptiert, sind aber nur als Eigenschaft responseText verfügbar.

getResponseHeader / getAllResponseHeaders

Bei einem HEAD-Request gibt der Server nur den Header einer Resource zurück – gerade genug, um den Content-Type oder das Datum der letzten Änderung (Last-Modified) zu erfahren, ohne das Dokument selbst zu öffnen.

Um einen HEAD-Request auszuführen, wird die open()-Methode mit einem HEAD-Request anstelle von GET oder POST aufgerufen und der Header entweder mit getAllResponseHeaders oder getResponseHeader("Name") um einen individuellen Wert zu lesen. Wenn getAllResponseHeaders aufgerufen wird, enthält die Antwort alle Header-Informationen als Name-/Wertpaar und die einzelnen Paare sind durch CR/LF voneinander getrennt.

var xmlhttp = null;
xmlhttp = new XMLHttpRequest();

xmlhttp.open("HEAD", "jsBeispiele/xml/data.xml", true);
xmlhttp.onreadystatechange=function() {
  if (xmlhttp.readyState==4) {
	 var res = document.createElement('pre');
	 var resText = document.createTextNode(xmlhttp.getAllResponseHeaders());
	 res.appendChild(resText);
	 httpHead.appendChild(res);
  }
}
xmlhttp.send(null);

Um einen einzelnen Wert abzurufen, wird xmlhttp.getResponseHeader('name') anstelle von xmlhttp.getAllResponseHeaders() aufgerufen.

xmlhttp.getAllResponseHeaders('Last-Modified');

Sicherheit: Javascript Sandbox

Wenn das XMLHttpRequest-Objekt innerhalb eines Browsers agiert, adaptiert der XMLHttpRequest die Sicherheitsstrategien einer typischen Javascript-Anwendung – die »Sandbox«-Politik.

  1. In den meisten Browsern kann eine Seite, die Skriptcode enthält, nur über das http- bzw. https-Protokoll geladen werden, so dass es nicht ohne Weiteres möglich ist, die Seiten auf dem lokalen Rechner zu testen (file- Protocol). Mozilla fordert, dass der Zugriff auf das Objekt in UniversalBrowserRead-Sicherheitsprivilegien erfolgt. IE hingegen öffnet ein modales Fenster, um den Benutzer von einem potentiellen Sicherheitsproblem zu benachrichtigen und ein Abbrechen der Funktion anzubieten.
  2. Der XMLHttpRequest unterlag in den frühen Versionen noch der Same Origin Policy (alles muss von derselben Domaine kommen): Die URL, die die Daten liefert, muss dieselbe sein wie die des Skripts. So konnten clientseitige Skripte keine Daten von anderen Seiten abrufen und in eine Seite einbinden.

Heute erlaubt XHR Cross Origin Requests, wenn CORS aktiviert ist und unterstützt wird. CORS (Cross-Origin Resource Sharing) ist eine Ebene über dem HTTP-Protokoll und benutzt zusätzliche HTTP-Header, z.B. um ein Bild von gertrud.de in eine Seite von susanne.de zu laden. Für das Laden von CSS-Dateien, Fonts und Scripts im HTML-Code ist das eine Selbstverständlichkeit. Scripte hingegen dürfen nicht ohne Weiteres Resourcen von anderen Domainen laden, es sei denn, dass CORS aktiviert ist.

var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
	// XHR Chrome / Firefox / Opera / Safari.
	xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
	// XDomainRequest IE
	xhr = new XDomainRequest();
	xhr.open(method, url);
} else {
	// CORS not supported.
	xhr = null;
}

Aspekte: History und Bookmarks

Schon die HTML-Technik der Frames und iFrames bot einen Ansatz, Teile einer Seite stehen zu lassen und nur relevante Daten auszutauschen. Frames gelten heute als veraltetet, da ihr Einsatz mit einer Reihe von schwerwiegenden Nachteilen verbunden ist. Seiten, die aus HTML-Frames aufgebaut sind, lassen sich nicht bookmarken und setzen die History des Browsers außer Kraft.

Auch beim eim Einsatz des XMLHttpRequest funktioniert die klassische History des Browsers nicht mehr, aber Window History wurde erweitert, um den Anforderungen von XHR und JSON entgegen zu kommen.

XMLHTTP