Kategorien
Webdesign

AJAX: Teil 2 – Das XMLHttpRequest Objekt

Die Idee zu AJAX gab es schon lange – erst mit dem XMLHttpRequest wurde eine browserübergreifende Möglichkeit eröffnet, um die asynchrone Kommunikation mit dem Server über JavaScript zu ermöglichen. Wir bitten zur Praxis. Das XMLHttpRequest Objekt hat die…

Die Idee zu AJAX gab es schon lange – erst mit dem XMLHttpRequest wurde eine browserübergreifende Möglichkeit eröffnet, um die asynchrone Kommunikation mit dem Server über JavaScript zu ermöglichen. Wir bitten zur Praxis.

Das XMLHttpRequest Objekt hat die asynchrone Kommunikation im AJAX Modell erst ermöglicht. Mit ihm kann man Daten im Hintergrund über JavaScript über http an Applikationen auf dem Server senden und die Antwort des Servers in Form von XML empfangen und verwerten. Die Vernetzung von JavaScript und serverseitiger Technologie wird über das Objekt ermöglicht und forciert.

Die Initialisierung funktioniert im Internet Explorer noch über ActiveX, während in anderen Browsern es als einfache Objektableitung geht. Eine einfache Javascript Funktion, mit der Ableitungen des Objektes erzeugt werden können und Anfragen an den Server verschickt werden, könnte wie folgt aussehen:

 var req;

    function loadXMLDoc(url) { //Übergabe der URL, an welche die Anfrage
    geschickt werden soll
    req = false;
    // für Mozilla etc.
    if(window.XMLHttpRequest) {
    try { //Fehler abfangen
    req = new XMLHttpRequest(); 
    } catch(e) {
    req = false;
    }
    // für den InternetExplorer
    } else if(window.ActiveXObject) {
    try {
    req = new ActiveXObject("Msxml2.XMLHTTP");
    } catch(e) {
    try {
    req = new ActiveXObject("Microsoft.XMLHTTP");
    } catch(e) {
    req = false;
    }
    }
    }
    if(req) { //falls Objekt erzeugt werden konnte…
    //bei Aenderung des Status der Anfrage, wird Funktion handleReqChange aufgerufen
    req.onreadystatechange = handleReqChange; 
    req.open("GET", url, true);
    req.send(null);
    }
    }

Mit den „try-catch“ Bereichen wird versucht ein Objekt zu erzeugen; wenn es nicht funktioniert, wird der Fehler abgefangen. Es gibt sowohl eine Anweisung für Mozilla und Co. als auch den InternetExplorer.

Im dritten Teil des Codes wird überprüft, ob ein Objekt erfolgreich erzeugt werden konnte. Ist dies der Fall, so wird die Anfrage erzeugt und an die im Funktionsaufruf übergebene URL per HTTP abgesendet. Die zu übergebenden Daten können zum Beispiel als Parameter an den URL angehängt werden. Bei einer Veränderung des Status der Anfrage, wird über den Eventhandler onreadystatechange die Funktion handleReqChange aufgerufen. Dieser Programmcode ist für alles Weitere essentiell.

Bevor genauer auf das Beispiel eingegangen wird, sollten Sie sich jedoch einen Überblick über die Methoden und Eigenschaften des XMLHttpRequest Objektes machen.

Methoden

  • getAllResponseHeaders()
    Gibt die gesamte Antwort des Servers als Zeichenkette zurück.
  • getResponseHeader(„headerLabel“)
    Gibt die Antwort des Servers unter dem Header „headerlabel“ zurück.
  • open(„method“, „URL“[, asyncFlag[, „userName“[, „password“]]])
    Schreibt die Ziel URL fest; weitere optionale Eigenschaften können angefügt werden.
  • send(content)
    Sendet die HTTP Anfrage
  • setRequestHeader(„label“, „value“)
    Fügt Werte in den Header der Anfrage hinzu.
  • abort()
    Die aktuelle Anfrage (Aktion) wird abgebrochen.

Mit diesen Methoden können Daten in Form von HTTPRequests abgeschickt werden. Nachdem eine Anfrage an den Server geschickt wurde, stehen dem Objekt mehrere Eigenschaften zur Verfügung, mit denen man zum Beipiel den Status des HTTPRequests abfragen kann.

Eigenschaften

  • readyState
    Gibt den Status des Objektes zurück:
    0 = nicht initialisiert
    1 = Wird geladen
    2 = Geladen
    3 = Interaktiv (d.h. es interagiert mit dem Server)
    4 = Completed
  • onreadystatechange
    Event handler, mit dem man jede Änderung des Status des Objektes verfolgen kann; bei unserem obigen Beispiel wird bei einer Veränderung des Status der Anfrage die Funktion handleReqChange aufgerufen.
  • responseText
    Die String-Version der Antwort des Servers auf eine Anfrage
  • responseXML
    Über diese Eigenschaft kann man auf die XML kompatible Antwort des Servers zugreifen.
  • status
    Der Statuscode, der vom Server auf die Anfrage zurückgeschickt wurde (z.B. Status 200 – alles ok)
  • statusText
    Zeichenkette, klurze Nachricht, die zum Statuscode hinzukommt; z.B. bei Status 500 – Internal Server Error.

Unser erstes AJAX Beispiel scheint zunächst relativ simpel, zeigt jedoch Möglichkeiten, wie man AJAX praktisch nutzen kann. Nehmen wir einmal an, dass Sie irgendwo Ihre Emailadresse eingeben müssen beziehungsweise wollen. Nun soll über JavaScript zunächst überprüft werden, ob die Emailadresse korrekt ist. Daraufhin wird auf der Serverseite durch einen Datenbankabgleich überprüft, ob die Emailadresse eventuell bereits in der Datenbank hinterlegt wurde. CSS soll zur Darstellung von Fehlermeldungen verwendet werden; das DOM ist hierfür essentiell. Das alles soll geschehen, ohne dass die Seite neu aufgerufen werden muss.

Beginnen wir mit dem schlichten HTML-Formular und dem dazugehörigen CSS-Code an.

      <input id="email" name="email" type="text" onblur="checkEmail(this.value,'')"
  /><br />
  <span class="hidden" id="emailCheckFailed">
  Die Emailadresse befindet sich bereits in der Datenbank
  </span>
  <span class="hidden" id="emailSyntaxCheckFailed">
  Falsche Syntax
  </span>

Es gibt zwei versteckte Span-Felder, die zwei vordefinierte Fehlermeldungen anzeigen können. Der dazugehörige CSS-Code sieht wie folgt aus:

      <style type="text/css">
  span.hidden{
  display: none;
  }
  span.error{
  color: #FF0000;
  }
  </style>

Bei onBlur, also wenn das Feld den Fokus verliert, wird die Funktion checkEmail aufgerufen; ihr wird zudem noch der Wert des Textfeldes übergeben, der daraufhin überprüft wird. Der zweite übergebene Parameter ist für die weitere Behandlung wichtig, denn mit der Funktion checkEmail wird sowohl die Eingabe des Nutzers untersucht, als auch die Antwort des Servers auf die Anfrage behandelt. Zunächst ist die übergebene Antwort natürlich leer – die Emailadresse, die eingegeben wurde, wird mit JavaScript auf korrekte Syntax überprüft. Ist das nicht der Fall (das heißt, wenn checkEmailSyntax false zurückgegeben hat), dann wird das zweite Span-Feld über das DOM angesprochen und die Fehlermeldung „Falsche Syntax“ angezeigt.

      function checkEmail(input, response)
    {

    if (response != ''){ 
    //etwaige Fehlermeldung für falsche Email-Syntax wird versteckt
    message = document.getElementById('emailSyntaxCheckFailed');
    message.className = 'hidden';

    // die Antwort des Servers wird untersucht
    message = document.getElementById('emailCheckFailed');
    if (response == 1){ //falls die Emailadresse bereits in der Datenbank liegt
    message.className = 'error'; //Fehlermeldung wird angezeigt
    }else{ 
    message.className = 'hidden';
    } 

    }else{
    // zunaechst wird Emailadresse clientseitig auf korrekte Syntax ueberprueft
    if(checkEmailSyntax(input)) {
    //ist Syntax korrekt, dann wird Anfrage gesendet
    //der Parameter wird an den URL angehaengt
    url = 'http://localhost/checkEmail.php?email=' + input; 
    loadXMLDoc(url);
    }
    else {
    //ist Syntax nicht korrekt, so wird entsprechende Fehlermeldung angezeigt
    message = document.getElementById('emailSyntaxCheckFailed');
    message.className = 'error'; //Aenderung der CSS Klasse
    }
    }
    }

Hier erkennt man schön die Verzahnung der Technologien mit AJAX. Die Überprüfung der Syntax der Emailadresse kann ohne weiteres direkt mit Javascript auf der Clientseite erfolgen. Hierzu muss man nicht ein Skript auf dem Server belasten; andererseits findet der Datenbankabgleich auf dem Server statt. Für die Überprüfung der Email-Syntax wurde auf die Funktion von Jan Winkler in einem früheren Dr. Web Artikel zurückgegriffen.

So sieht’s aus, wenn die Emailsyntax nicht stimmt

So sieht’s aus, wenn die Emailsyntax nicht stimmt

Wie bereits oben erwähnt, muss überprüft werden, ob die Anfrage an den Server erfolgreich war. Dazu wird bei jeder Statusveränderung der Anfrage die Funktion handleReqChange aufgerufen. Hat die Anfrage den Status „completed“ erreicht und hat die Serverantwort den Status 200 (das heißt: alles okay), dann kann die XML Antwort des Servers verarbeitet werden. Die XML Antwort könnte zum Beispiel so aussehen:

      <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <response>
    <method>checkEmail</method>
    <result>1</result>
    </response>

Dabei wird berücksichtigt, dass in einem Skript auch mehrere Funktionen gleichzeitig aufgerufen werden können und so das Skript eventuell auch mehrere Ergebnisse zurücksendet. Deshalb wird der Name der Funktion auch übergeben.

Die Funktion handleReqChange, welche die Antwort behandelt, sieht wie folgt aus:

      function handleReqChange() 
    {
    // Wenn der Status der Anfrage "completed" ist
    if (req.readyState == 4) {
    // wenn die Server Nachricht den Statuscode 200 hat
    if (req.status == 200) {
    // hier wird die XML Antwort verarbeitet
    response = req.responseXML.documentElement;
    result = response.getElementsByTagName('result')[0].firstChild.data; //hier
    wird der Rueckgabewert ermittelt
    checkEmail('',result); //dieser wird zurueck an die Funktion checkEmail geleitet
    } else {
    alert("Beim Empfangen der XML Daten ist ein Fehler aufgetreten\n" + req.statusText);
    }
    }
    }
    
      response = req.responseXML.documentElement;

die Serverantwort angesprochen. Über

      result = response.getElementsByTagName('result')[0].firstChild.data;
    

wird die Antwort des Servers im XML-Tag <result> ermittelt.
Daraufhin wird die Funktion checkEmail erneut aufgerufen, wobei dieses mal der erste Parameter leer ist und der zweite (d.h. die Serverantwort) gesetzt ist. Entsprechend des Ergebnisses der Datenbankabfrage wird die Fehlermeldung angezeigt.

Nun fehlt nur noch das PHP-Skript, welches per Javascript angerufen wird. Hier kann man z.B. eine Textdatei öffnen und nach der Emailadresse suchen, oder etwa einen Datenbankabgleich machen.

      <?php
    header('Content-Type: text/xml');

    function checkEmail($email)
    { 
    /* hier wird der Datenbankabgleich gemacht */
    return 1; 
    }
    ?>
    <?php echo '<?xml version="1.0" encoding="UTF-8"
    standalone="yes"?>'; ?>
    <response>
    <method>checkEmail</method>
    <result><?php 
    echo checkEmail($_GET['email']) ?>
    </result>
    </response>

Wichtig ist, dass der Content-Type auf text/xml gesetzt wird, da sonst das XMLHttpRequest-Objekt nicht mit der Antwort zurechtkommt.

Nun, das war eine Menge Stückwerk. Es zeigt sich, dass AJAX doch recht kompliziert ist, da man nicht ein ganzes Programm hat, sondern verschiedene kleine Sinneinheiten, die nur gemeinsam optimal funktionieren. Das Beispiel an und für sich ist trivial, doch nur so gelingt der Einstieg ohne Probleme. Weitere AJAX Beispiele, bei denen deutlich wird, was man alles anstellen kann, finden sich bei Clearnova. Die dazugehörigen Quelldateien für unser Beispiel gibt es „in einem Guss“ zum Download, zum genauen Studium.

Und so sieht es schließlich aus:

Falls die Emailadresse bereits gespeichert ist – die Antwort hat man, ohne das die Seite neu geladen werden musste!
Falls die Emailadresse bereits gespeichert ist – die Antwort hat man, ohne dass die Seite neu geladen werden musste

Erstveröffentlichung 02.09.2005

Von Thiemo Fetzer

Thiemo Fetzer lebt seit 2008 in London und promoviert dort im Fachbereich "Entwicklungsökonomie" an der London School of Economics. Zuvor hat er Wirtschaftswissenschaften, Mathematik und Informatik in Magdeburg und Ulm studiert.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.