CSS, HTML und Javascript mit {stil}

Javascript XMLHttpRequest und Ajax

XMLHttp Request – Datenaustausch Client Server

AJAX (Asynchronous Javascript And XML) tauscht Daten zwischen einem Programm auf dem Server und dem Benutzer im Hintergrund aus. Dabei muss die Seite nicht komplett neu geladen werden.

Der XMLHttpRequest oder kurz XHR prüft z.B. Formulareingaben gegen die Datenbank ohne Hin- und Her zwischen Client und Server. Mit AJAX begann »Web2«.

Bei der klassischen Webanwendung hingegen (z.B. bei einem PHP-Programm) lösen Aktionen des Benutzers einen HTTP-Request zurück zum Server aus.

XML HTTP Request – XHR

Der Server 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 und nur wenige Inhalte wurden tatsächlich verändert.

Über viele Jahre haben Webentwickler nach einer sauberen Technik gerufen, die eine Verbindung zum Server aufrecht erhält, während Transaktionen im Hintergrund ablaufen und frisch angelieferte Daten in die Seite integriert werden.

Daten nachladen

Als das W3C im April 2004 die Document Object Model (DOM) Level 3 Load and Save Specification zum Standard erhob, hatte Microsoft die Lücke bereits mit dem XMLHttpRequest-Objekt geschlossen und die Mainstream-Browser übernahmen den XMLHttpRequest in Windeseile.

Mit XMLHttpRequest Object W3C Working Draft 15 April 2008 übernahm das W3C den XMLHttpRequest. Die Load and Save Specification hingegen ist beim W3C verstaubt und vergessen.

Datenübertragung zwischen Javascript und Server

Der XMLHttpRequest bildet eine Schnittstelle zwischen einem Script und Daten oder einer Anwendung auf dem Server. Der XMLHttpRequest überträgt Daten von und zum Server im Hintergrund. So kann ein Skript Teile einer Seite neu liefern, ohne die komplette Seite neu zu laden.

Diese Technik ist als »Ajax« (Asynchronous Javascript And XML) bekannt geworden und hat dem Web seit etwa 2005 ein neues Gesicht gegeben: Mit Web 2.0 verschwinden die Grenzen zwischen Desktop- und Online-Anwendung.


Mit dem XMLHttpRequest sendet ein Javascript z.B. die Anforderung einer Datei an den Server und kann die Daten direkt per DOM und CSS in das Dokument einbinden, ohne das gesamte HTML-Dokument neu zu laden.

Wer jetzt hier glaubt, der XMLHttpRequest sei etwas für XML-Dokumente: Der Name »XMLHttpRequest« ist irreführend.

  • Zunächst einmal unterstützt das Objekt neben XML alle textbasierten Formate.
  • Zweitens kann das Objekt einen Request sowohl über HTTP als auch über HTTPS senden.
  • Am Ende unterstützt das Objekt sowohl Requests als auch die Antworten.

Wie der XMLHttpRequest funktioniert

Der XMLHttpRequest öffnet eine Verbindung zu einer URL auf dem Server und sendet einen HTTP-Request über diese Verbindung. Die Daten können in Form einer XML-Datei auf dem Server liegen, als flacher Text oder von einer PHP-Anwendung als Antwort auf einen GET- oder POST-Request des XMLHttpRequests übertragen werden.

Das eröffnet Javascript-Anwendungen eine asynchrone Verarbeitung von Daten innerhalb einer persistenten (beständigen) Verbindung anstelle der typischen Stop-and-Go-Komminikation herkömmlicher Anwendungen.

Muster: XML-Datei lesen

Auf dem Server liegen Daten in einer XML-Datei (data.xml).

<?xml version="1.0" encoding="UTF-8"?>
<data>
  <buchliste>
   <buch>
     <titel>Das Universum in einer Nussschale</titel>
     <autor>Stephen Hawking</autor>
     <jahr>1980</jahr>
   </buch>
   <buch>
     <titel>Ab die Post!</titel>
     <autor>Terry Pratchet</autor>
     <jahr>2003</jahr>
   </buch>
   …
  </buchliste>
</data>

Datensätze zeigen

Im HTML
<p class="showList">
  <a href="data.xml">Datensätze zeigen</a>
</p>
XMLHTTPRequest auslösen
var showList = document.querySelector('.showList a');
showList.addEventListener('click', function (evt) {
   var showXML = processXMLHttpRequest(this.href, this.parentNode);
   evt.preventDefault();
});

Der Klick auf den Link ruft processXMLHttpRequest mit den Parametern this.href (href-Attribut des a-Tags) und location auf. file ist der Name der XML-Datei, die per XMLHttpRequest nachgeladen wird (also data.xml). location ist eine Referenz auf das HTML-Element, in dem der Link liegt.

Wenn im Browser des Benutzers Javascript nicht aktiviert ist, folgt die Navigation dem Link zur XML-Datei.

XMLHTTPRequest: open() und send()

Die gebräuchlichste Anweisungssequenz für einen XMLHttpRequest besteht aus

  1. dem Erzeugen einer Instanz des XMLHttpRequest-Objekts
  2. der Aufruf der open()-Methode
  3. dem Senden des Requests mit der send()-Methode
  4. Abfragen von onreadystatechange und Aufruf einer Funktion, die beim Eintreffen der Antwort die Verarbeitung übernimmt.
function processXMLHttpRequest(file, location) {
   var xmlObj = new XMLHttpRequest();
   
   xmlObj.onreadystatechange = function() {
      if(xmlObj.readyState == 4) {
         processXML(xmlObj.responseXML, location);
      }
   }
   xmlObj.open ('GET', file, true);
   xmlObj.send ('');
   return false;
}

Die zurückgegebene Objektreferenz beider Konstruktoren ist ein XMLHttpRequest-Objekt, dessen Methoden alle Operationen steuern und dessen Eigenschaften die Daten, die vom Server zurückgeliefert werden, speichern.

xmlObj.onreadystatechange = function() {
   if(xmlObj.readyState == 4) {
      processXML(xmlObj.responseXML, location);
   }
}

Die letzten Anweisung öffnen die Verbindung zur Datei XML-Datei file auf dem Server und senden einen GET-Request.

xmlObj.open ('GET', file, true);
xmlObj.send ('');

processXML() wird aufgerufen, wenn readyState == 4 ist und parst die Elemente der XML-Datei. Der Einfachheit zuliebe werden die ausgelesenen Daten in einem PRE-Element ausgegeben, das am Ende das .classList-Element mit dem Link ersetzt.

function processXML(obj, location) {
   var rows = obj.getElementsByTagName('buch');
   var listBox = document.createElement('pre');
   var listText = "";
   for (var i=0, row; row=rows[i]; i++) {
      var elems = row.childNodes;
      for (var j=0, srow; srow=elems[j]; j++) {
         if (srow.nodeType == 1) {
            listText += srow.firstChild.data + "   ";
         }
      }
      listText += "\n";
   }
   text = document.createTextNode(listText);
   listBox.appendChild(text);
   location.parentNode.replaceChild(listBox, location, listBox);
}

Prüfen, ob ein Bild oder ein Link existiert

(function(){
   var request = new XMLHttpRequest();  
   request.open('GET', 'http://www.mediaevent.de/xmlhttp.png', true);
   request.onreadystatechange = function(){
      if (request.readyState === 4){
         if (request.status === 404) {  
            alert("Da ist nichts zu sehen …");
         } else {
            document.querySelector('.console').innerHTML = "Das Bild gibts";
         }
      }
   };
   request.send();
})();