9.5.06

AJAX KnowHow2

Nicht nur XML

Aber wo bleibt XML, schließlich trägt Ajax es doch im Namen? XMLHttpRequest übermittelt einfach nur die Antwort desWebservers. Um welches Datenformat es sich dabei handelt, ist egal. Es kann wie im Beispiel Text sein, eine XML-Datei oder HTML-formatierte Texte. Die Auswahl des Formats ist vor allem davon abhängig, wie sich die Server-Antworten am einfachsten verarbeiten lassen.
XML-Daten speichert XMLHttpRequest nicht nur in ResponseText, sondern zusätzlich in der Eigenschaft ResponseXML. Dabei handelt es sich um einen Objektbaum nach dem Document Object Model (DOM), auf den Sie mit den entsprechenden Methoden von JavaScript zugreifen. Das kann im Detail ziemlich komplexwerden. Weil DOM mit Ajax und XMLHttpRequest eigentlich nichts zu tun hat, verwenden alle Beispiele in diesem Artikel das Textformat für die Antwort des Webservers.

Rückruf vom Browser

Die Callback-Funktion muss einiges prüfen. Der Browser ruft die Funktion nicht nur auf, wenn die Antwort vom Webserver eingetroffen ist. Je nach Browser gibt es mehrere Zwischenstadien, etwa wenn die Anfrage erfolgreich versandt wurde. Das Listing zeigt dies:

function BearbeiteAntwort ()
{
var antwort="";
if (AbfrageObjekt.readyState == 4){
if (AbfrageObjekt.status == 200) {
antwort=AbfrageObjekt.responseText;FuelleListe(antwort);
} } };

Die Eigenschaft readyState des XMLHttpRequest- Objekts signalisiert den Fortschritt der Anfrage. Entscheidend ist dabei der Wert 4, der den Abschluss der Anfrage anzeigt. Das bedeutet noch nicht, dass die Bearbeitung auf dem Webserver erfolgreich verlaufen ist. Wie bei einer normalen Anfrage des Browsers an einen Webserver gibt es Fehlercodes, die in der Eigenschaft status hinterlegt sind. Ein Wert von 200 bedeutet, dass alles erfolgreich verlaufen ist. Der aus dem Browser bekannte Wert 404 signalisiert hingegen, dass die URL nicht gefunden wurde.
responseText enthält das Ergebnis der Suchanfrage für die Postleitzahlen in der Datenbank. Die Funktion FuelleListe() zerlegt im Beispiel die Server-Antwort in die einzelnen Postleitzahlen und trägt diese in die Auswahlliste im Webformular ein.
Das Beispiel erfüllt nur Minimalanforderungen. So wäre etwa eine Timerfunktion sinnvoll, die nach einer Wartezeit auf die fehlgeschlagene Webserver-Anfrage hinweist und diese abbricht. Dann wartet das XMLHttpRequest- Objekt nicht länger auf eine Antwort und ruft auch die Callback-Funktion nicht mehr auf. Sie erreichen das mit der Methode
AbfrageObjekt.abort().

Fertige Frameworks

Auch wenn der JavaScript-Code im Beispiel nicht umfangreich ist, warten bei der Programmierung Fallstricke. Zum einen gibt es zwischen den Browsern Unterschiede. Viel tückischer ist aber, dass mehrere Komponenten beteiligt sind. Eine Anfrage durchläuft die Stationen Browser-Skript, XMLHttpRequest-Objekt, Webserver, XMLHttpRequest-Objekt, Browser-Skript. Es kann sehr mühsam sein, herauszufinden, an welcher Stelle ein Fehler auftritt. Doch es gibt Frameworks (Module) für Ajax. Manche sind als JavaScript-Paket für den Browser konzipiert, die Verarbeitung auf dem Webserver müssen Sie übernehmen.
Typische Vertreter sind Sarissa und Prototype. Andere Frameworks laufen auf dem Webserver mit Programmiersprachen wie PHP, ASP.Net, Java und Python. Bevor Sie sich für ein Framework entscheiden, sollten Sie genau wissen, welche Aufgaben Ajax erledigen soll. Achten Sie darauf, dass das Projekt weiter gepflegt wird – sonst stehen Sie beim Browser-Update vor Skriptfehlern und müssen aufwändig das Framework wechseln.


Das Objekt XMLHttpRequest

EigenschaftErklärung
onreadystatechangeDie Callback-Funktion, die bei einer Änderungen des Anfragestatus aufgerufen wird
readyStateDer aktuelle Status der Anfrage
responseTextDie Antwort des Webservers als Zeichenkette
responseXMLDie Antwort des Webservers als DOM-Objektbaum, falls es sich um gültiges XML handelt
statusHTTP-Antwort-Code des Webservers, zum Beispiel 404 für eine nicht erreichbare URL
statusTextKurze Beschreibung des HTTP-Antwort-Codes, zum Beispiel „Nicht gefunden ...“
MethodeErklärung
abort()Stoppt eine Anfrage und setzt readyState auf 0 zurück.
open()Bereitet eine Anfrage vor. Die Parameter: Anfragemethode, URL, Synchronstatus, Benutzername, Passwort. Nur die beiden ersten Parameter sind Pflicht, ohne Angabe ist der Synchronstatus true (asynchrone Anfrage). Passwort und Benutzername dienen, falls erforderlich, zum Einloggen auf dem Webserver.
send()Schickt die Anfrage an den Webserver ab, als Parameter ist „null“ zu übergeben.


AJAX KnowHow1

Interaktive Webseiten


Während Sie den Suchbegriff eintippen, zeigt Google bereits Vorschläge für den kompletten Suchbegriff mit der Anzahl der Fundstellen an.
Immer mehr Websites setzen auf diese Technik namens Ajax, die noch viel mehr leisten kann als bei Google Suggest. Unter www.zimbra.com finden Sie etwa die Demo eines Personal Information Managers, der sich fast wie Outlook bedient. Nach der ersten Anzeige der Webseite ist kein weiterer Ladevorgang erforderlich. Klicken Sie beispielsweise den Kalender an, so ändert sich die Anzeige im Browserfenster und die vorhandenen Einträge werden angezeigt. Diese Daten holt Zimbra per Ajax fast unbemerkt vom Webserver, auf dem sie gespeichert sind. Ähnlich funktionieren auch Google Mail und OutlookWeb Access.

Ajax steht für Asynchronous JavaScript and XML. Schon der Name stellt klar, dass es dabei nicht um eine neue Technologie geht, sondern um eine Kombination bekannter und etablierter Techniken: XML als Datenformat, JavaScript zur Verarbeitung der Daten, aber wie kommunizieren Browser und Webserver? Browser-basierende Anwendungen wie Adressbücher, Webmail oder Webseiten-Baukästen haben nicht ganz zu Unrecht den Ruf, umständlich und langsam zu sein. Denn bei jeder Änderung der Anzeige muss der Webserver eine komplett neue Webseite senden, die der Browser dann berechnen und anzeigen muss. Das ist zum Beispiel der Fall, wenn in einer Adressdatenbank alle Namen mit F zu suchen sind. Selbst bei einer schnellen Internetverbindung dauert der Vorgang deutlich länger als bei einem Programm, das auf dem lokalen PC läuft.

Der Kern: XMLHttpRequest

Für diesen Anwendungszweck hat Microsoft 1999 in den Internet Explorer 5.0 eine besondere Programmierschnittstelle eingebaut, XML HttpRequest. Die erste Anwendung war OutlookWeb Access, die Online- Variante des bekannten Programms. Mittlerweile unterstützen fast alle aktuellen Browser die Schnittstelle: Internet Explorer (seit 5.0), Mozilla Firefox (seit 1.0), Netscape 7.1, Opera 7.6, Apple Safari 1.2 und der Linux Konqueror.
XMLHttpRequest nimmt Aufträge entgegen, leitet diese an den Webserver weiter und holt später die Antwort desWebservers ab. Als Programmierer müssen Sie sich nicht um die Details der Kommunikation kümmern.
Damit XMLHttpRequest mit dem Webserver kommunizieren kann, benutzt es das Standardprotokoll von Webbrowser und Webserver, HTTP. Dabei schickt der Webbrowser eine Anfrage (request) an den Webserver. Dieser reagiert entsprechend der Anfrage und sendet die angeforderten Daten als Antwort (response) zurück. Dabei kann es sich z. B. um die Ergebnisse einer Datenbanksuche oder einer Berechnung handeln. Der Webbrowser zeigt die Antwort nicht im Browserfenster, sondern speichert sie im Objekt XMLHttpRequest. Ein Browser-Skript liest diese Daten und reagiert entsprechend, etwa indem es in einem Formular auf der Webseite den Namen eines Kunden einträgt.

Drei Zeilen JavaScript

Ein kleines Praxisbeispiel zeigt die Zusammenhänge. In einem Webformular soll nach der Eingabe der Stadt eine Auswahlliste die dazu passenden Postleitzahlen anzeigen. Dann muss ein Besucher nur noch die richtige Zahl auswählen, das reduziert Fehleingaben. Auf dem Webserver gibt es dazu eine MySQL-Datenbank mit Ortsnamen und Postleitzahlen sowie ein kleines PHP-Skript, getplz.php, das die Suche in der Datenbank übernimmt. Drei Zeilen JavaScript reichen für eine minimale Ajax-Anwendung aus. Fehlerkontrolle und Komfort gibt es dabei natürlich nicht, außerdem funktioniert das Beispiel in dieser Form nur im Internet Explorer:

AbfrageObjekt = newActiveXObject("Microsoft.XMLHTTP");

AbfrageObjekt.open("GET","getplz.php?frag=Dortmund", false);

AbfrageObjekt.send(null);


Die erste Zeile erzeugt eine neue Objektinstanz vom Typ XMLHttpRequest. Microsoft realisiert das Objekt als ActiveX-Control, weshalb diese spezielle Syntax erforderlich ist. Alle anderen Browser nutzen die bei Java- Script übliche Methode über new XMLHttpRequest().
Nachdem das Objekt erzeugt ist, legen Sie mit der Methode open die Eckdaten für die Anfrage fest. Der erste Parameter beschreibt die Methode, mit der Daten zum Webserver übertragen werden. Kurze Texte übertragen Sie mit der Methode GET. Dabei hängen Sie die Daten einfach an die URL desWebservers an, an den Sie die Anfrage richten. Diese Methode setzen viele Webformulare ein, um eingetippte Suchbegriffe von Google zum Server zu schicken. Hängen Sie nach einem Fragezeichen die Daten alsWertepaar Name=Wert an die URL an. Das Beispiel ruft das PHPScript getplz.php auf dem Webserver auf und übergibt den Parameter frag mit dem Wert Dortmund. Das Script sucht in einer MySQLDatenbank nach der oder den passenden Postleitzahlen zum angegebenen Ort.

Antwort vom Webserver


Bei einer synchronen Anfrage an den Webserver ist der Browser blockiert, bis die Ergebnisse zurückkommen.
Der letzte Parameter kann nur true oder false sein. Lassen Sie ihn weg, so gilt als Standardwert true. Mit dem Wert false wie im Beispiel startet eine synchrone Kommunikation: Der Browser wartet nach dem Absenden der Anfrage auf die Antwort vom Webserver. In dieser Wartezeit ist der Webbrowser blockiert, der Anwender kann weder scrollen noch klicken oder sonst etwas tun.
In der Praxis entspricht die erzwungene Wartezeit nicht dem gewünschten Verhalten. Im nächsten Abschnitt lesen Sie, wie eine asynchrone Anfrage das Warteproblem löst.
Bis jetzt ist noch nichts passiert, das AbfrageObjekt ist lediglich mit den richtigen Werten initialisiert. Das Absenden der Anfrage erledigt die Methode send in der letzten Zeile. Der einzige Parameter ist optional. Sie sollten aber immer null eintragen, sonst meldet zum Beispiel Firefox einen Fehler.
Das Ergebnis der Abfrage beim Webserver speichert das AbfrageObjekt in der Eigenschaft ResponseText. Dabei kann es sich entweder um die gewünschten Ergebnisse oder um eine Fehlermeldung handeln. Die Zeilealert

(AbfrageObjekt.ResponseText);


gibt den Text in einer Dialogbox aus. Ein sinnvolles Skript würde die Daten in die Webseite einfügen oder etwa die Elemente eines Webformulars anpassen. ResponseText enthält lediglich eine Zeichenkette. Im Beispiel besteht der Text aus den ermittelten Postleitzahlen, die jeweils ein Minuszeichen trennt. Auf dem Webserver arbeitet im Beispiel ein PHP-Skript, das den Ortsnamen oder die ersten Buchstaben davon als Parameter entgegennimmt. Es sucht aus einer MySQL-Datenbank die passenden Ortsnamen und die zugehörigen Postleitzahlen heraus. Die Rückmeldung an den Webbrowser erfolgt über das Standardkommando echo. So kann die zentrale PHP-Schleife zur Ausgabe der Postleitzahlen aussehen:

while ($line =mysql_fetch_array($result,MYSQL_ASSOC))

{foreach ($line as $col_value){ echo "$col_value"."-";} }


Das Skript schreibt jeweils eine Postleitzahl, gefolgt von einem Minuszeichen. Das Minuszeichen erleichtert im Browser-Skript die Zerlegung der Postleitzahlen, denn es gibt sowohl fünf- als auch vierstellige Postleitzahlen. Anstatt PHP kann auch jede andere Programmiersprache oder Technologie zum Einsatz kommen, die GET-Anfragen von Webbrowsern empfangen und beantworten kann, etwa Perl, Java oder auch ASP.

Asynchroner Datenverkehr

Anhand der Eingaben im Ortsfeld blendet Java- Script in der Auswahlliste die entsprechenden Postleitzahlen zur Auswahl ein.
Das Beispiel erweitern Sie für die Praxis: In einem Webformular für eine Adresseingabe soll eine Auswahlliste die passenden Postleitzahlen enthalten, sobald der Benutzer das Eingabefeld mit dem Ortsnamen ausgefüllt hat und zum nächsten Feld wechselt. Dabei soll keine lästige Wartezeit stören.
Eine asynchrone XMLHttpRequest-Anfrage an den Webserver zu senden, funktioniert im Prinzip wie bei der beschriebenen synchronen Variante. Weil dasSkript nicht auf die Antwort desWebservers wartet, setzen Sie eine so genannte Callback-Funktion (Rückruf) ein. Das ist eine normale JavaScript-Funktion, die Sie selbst programmieren. Ändert sich der Status der Webserver-Anfrage, ruft das XMLHttpRequest- Objekt diese Funktion auf. Über die Eigenschaft onreadystatechange des Objekts legen Sie die Callback-Funktion fest:

AbfrageObjekt.open("GET",aktion,true);

AbfrageObjekt.onreadystatechange =BearbeiteAntwort;AbfrageObjekt.send(null);


Das Beispiel verwendet bei open als letzten Parameter true, um eine asynchrone Anfrage zu starten. Wichtig ist die Zeile danach, die der Eigenschaft onreadystatechange den Namen der Callback-Funktion, BearbeiteAntwort, zuweist.

Nvidia's GauGan App

NVIDIA's GauGAN AI Machine Learning Tool creates photorealistic images from Simple Hand Doodling http://nvidia-research-mingyuliu.com/...