Text direkt in einer Webseite ändern, ganz ohne lästiges Formular? Drag & Drop von Thumbnails in der eigenen Bildergalerie? Mit AJAX sind interaktive Websites kein Problem.
Wer interaktive Webseiten benutzt, braucht oft eine Menge Geduld. Hat man ein Formular mit einer Reihe von Eingabefeldern ausgefüllt und abgeschickt, heißt es erst einmal warten, bis der Server die Daten auswertet und als Antwort eine neue Seite ausliefert (Abbildung 1).
Seit einiger Zeit umgehen Websites wie Google Mail dieses Problem, indem sie die so genannte AJAX-Technik anwenden, die unter Webentwicklern als letzter Schrei gilt. Statt mit jeder Anfrage eine Seite komplett neu anzufordern, fragt der Webbrowser nur kleine Fragmente an Information ab, die er anschließend in die bestehende Webseite integriert. Das Ergebnis für den Benutzer: Eine Website fühlt sich damit beinahe so schnell an wie eine Desktop-Anwendung.
Der Name AJAX geht zurück auf den Essay “AJAX: A New Approach to Web Applications” von Jesse James Garrett [1]. Obwohl es sich nach Garretts Worten dabei nicht um ein Akronym handelt, interpretiert man AJAX meist als Kürzel für Asynchronous Javascript und XML. AJAX-Webseiten bestehen nicht nur aus statischen HTML-Dateien (und CSS-Stylesheets), sondern auch aus Javascript-Code, der abläuft, wenn der Benutzer auf einen Link klickt oder ein anderes so genanntes Event auslöst. Die Javascript-Funktionen fragen vom Server neue Daten an, die dieser als XML (deshalb das X), aber auch als HTML und in anderen Formaten zurück liefert.
Asynchron
Weil die Anfrage asynchron abläuft (das A), kann der Benutzer mit anderen Teilen der HTML-Seite weiter interagieren, der Browser ist nicht blockiert. Eine asynchrone Anfrage entkoppelt Anfrage und Antwort: Hat der Javascript-Code im Browser seine Anfrage abgeschickt, läuft er einfach weiter. Erst, wenn die Antwort beim Browser eintrifft, ruft dieser eine vorher festgelegte Javascript-Funktion auf. Die wiederum trägt das Ergebnis in die bestehende HTML-Seite ein. Das kann ein einzelner Zahlenwert in einer HTML-Tabelle sein, strukturierte Daten in XML oder JSON (Javascript Object Notation), Formularwerte und so fort.
Google Mail zum Beispiel kann so in den Arbeitsbereich in der Mitte des Browserfensters einen Editor zum Mail-Schreiben laden, eine Mail anzeigen oder die Nachrichten auflisten (Abbildung 2). Andere Beispiele für den nützlichen Einsatz von AJAX sind die Web-2.0-Anwendungen Flickr und Del.icio.us.
Schnellstart
Für den Anfang soll ein eine sehr einfache Webanwendung das Funktionsprinzip von AJAX veranschaulichen: Auf den Klick des Benutzers hin lädt der Browser eine Zufallszahl vom Server und zeigt sie an der dafür vorgesehenen Stelle in der Webseite an.
Die Anwendung besteht aus drei Komponenten: der statischen HTML-Startseite, dem Javascript-Code und einem Serverskript, welches das Ergebnis (die Zufallszahl) liefert. Was Sie dazu auf jeden Fall brauchen, ist ein Webserver (meist Apache), der eine Skriptsprache unterstützt, in unserem Beispiel PHP. Allerdings können Server und Browser zum Ausprobieren der AJAX-Technik auch auf dem gleichen Rechner laufen, selbst dem normalen Desktop-Computer.
Sind Ihnen Installation und Konfiguration von Apache und PHP mit den distributionseigenen Paketen und Tools zu kompliziert, können Sie es auch mit einem der beliebten LAMP oder XAMPP-Pakete versuchen. Sie enthalten nicht nur Apache und PHP, sondern auch die MySQL-Datenbank, die zwar nicht obligatorisch, aber für dynamische AJAX-Anwendungen doch nützlich ist.
Die HTML-Datei der AJAX-Beispielanwendung ist recht einfach aufgebaut (Listing 1). Im Header-Abschnitt bindet der Script-Tag eine externe Javascript-Datei namens ajax.js ein, die den gesamten Code der AJAX-Anwendung enthält. Alternativ dazu können Javascript-Funktionen auch direkt in der HTML-Datei stehen, eingeschlossen zwischen einem öffnenden und einem schließenden Script-Tag.
Die Verbindung zwischen Code und HTML stellt Zeile 6 des Listings her. Das Attribut onclick des Links enthält den Namen der Javascript-Funktion, die der Browser aufruft (getRandom), wenn der Benutzer darauf klickt. Schließlich folgt ein HTML-Bereich (span) mit einer ID, über die jener sich später von Javascript aus ansprechen lässt.
Listing 1
<html>
<head>
<script language="JavaScript" type="text/javascript" src="ajax.js"/>
</head>
<body>
<a href="#" onclick="javascript:getRandom()">AJAX-Test</a>
</body>
</html>
Wollen Sie einmal testen, ob die Verbindung HTML/Javascript klappt, tragen Sie in die Datei folgenden Code ein:
function getRandom()
{
alert("Angeklickt");
}
Befinden sich index.html und ajax.js im selben Verzeichnis auf dem Server, zum Beispiel ajaxtest, rufen Sie die HTML-Seite über die Adresse http://Servername/ajaxtest/ auf. Laufen Server und Browser auf dem gleichen Rechner, verwenden Sie als Servernamen localhost. Klicken Sie dann auf den Link, öffnet der Browser einen Dialog, der den Text Angeklickt anzeigt.
Klappt das nicht, können Sie sich schon einmal mit der Fehlersuche vertraut machen. Am besten verwenden Sie für die Entwicklung von AJAX- und anderen Webanwendungen den Browser Firefox, der einige dafür praktische Tools mitbringt. So finden Sie im Menü Tools den Punkt JavaScript Console, der ein kleines Fenster für Javascript-Fehlermeldungen.
Sehr vielfältig sind die Fehlerquellen in diesem einfachen Fall noch nicht. Entweder findet der Server die Javascript-Datei nicht (achten Sie beim Namen auch auf richtige Groß- und Kleinschreibung) oder sie enthält einen Syntaxfehler: Es fehlt also eine Klammer, ein Strichpunkt oder Ähnliches.
Verbindung zum Server
Bisher schickt der Browser nur je eine Anfrage für die HTML-Seite und die Javascript-Datei an den Server. Damit ist die Kommunikation abgeschlossen, und auch beim Klicken auf den Link nehmen die beiden keinen Kontakt mehr auf. Um weitere Daten vom Server zu holen, muss der Javascript-Code zunächst ein so genanntes Anfrage-Objekt (Request-Objekt) anlegen. Das übernimmt die Funktion XMLHttpRequest(), von der AJAX sein X im Namen bezieht. Das neu erzeugte Request-Objekt weist der folgende Befehl der Variablen request zu:
request = new XMLHttpRequest();
Das Request-Objekt besitzt einige Methoden, die im Folgenden zur Kommunikation mit dem Server wichtig sind. Als erstes legt request.open() die Parameter der anschließenden Verbindung fest.
Der erste Parameter bestimmt die HTTP-Methode (GET oder POST), dann folgt die zu kontaktierende Webadresse (URL). Der nächste Parameter legt fest, ob der Zugriff asynchron geschehen soll (in diesem Fall ist der Wert true). Zwei weitere, optionale Parameter enthalten Benutzername und Passwort für zugriffsgeschützte Seiten. Steht in der Javascript-Variablen url die Adresse http://localhost/~oliver/ajax/test.php, bereitet die folgende Zeile die Verbindung vor:
request.open("GET", url, true);
Bevor Sie die Anfrage an den Server schicken, müssen Sie noch die Funktion festlegen, die der Browser aufruft, wenn er die Antwort erhält. Sie erinnern sich: Weil die Browser und Server asynchron kommunizieren, wartet der Browser nicht auf die Server-Antwort. Diese so genannte Callback-Funktion festzulegen legen Sie über das Feld onreadystatechange des Request-Objekts fest.
Wie der Name nahe legt, ruft der Browser die Callback-Funktion allerdings nicht nur auf, wenn er die Antwort erhalten hat, sondern immer wenn sich der Zustand des Request-Objekts ändert (state change). Insgesamt gibt es fünf Zustände, in denen es sich befinden kann, von unbenutzt (0) bis abgeschlossen (4).
Auf die Antwort warten
Schließlich schicken Sie die Anfrage mit der Methode send an den Server, die als optionale Parameter eventuelle Nutzdaten verarbeitet, zum Beispiel Benutzereingaben in Formularen.
Weil es in diesem einfachen Beispiel keine solchen Daten gibt, erhält send nur den leeren Parameter null. Listing 2 zeigt das komplette Listing der simplen AJAX-Anwendung. Als Callback-Funktion wird in Zeile 10 checkResult() eingetragen, das bei jedem Aufruf den aktuellen Zustand des Requests in einem Dialog ausgibt.
Listing 2
function checkResult()
{
alert("Neuer Zustand: " + request.readyState);
}
function getRandom() {
request = new XMLHttpRequest();
var url = "http://localhost/~oliver/ajax/index.html";
request.open("GET", url, true);
request.onreadystatechange = checkResult;
request.send(null);
}
Weil der Browser in diesem Beispiel mit der Antwort des Servers nichts anfängt, brauchen Sie sich auch nicht dabei zu verrenken, ein PHP-Skript zu schreiben. Sie können zur Demonstration den Request wie in Listing 2 mit der Index-Seite selbst durchführen. Die Verwendung des Request-Objekts und der Callback-Funktion ändert sich dadurch nicht.
Erscheinen keine Dialogfenster, geht es wieder an die Fehlersuche. Vielleicht haben Sie sich bei der Eingabe der URL-Variablen vertippt? Kopieren Sie den String (ohne Anführungszeichen), fügen Sie ihn in das Adressfeld eines neuen Browserfensters ein und drücken Sie die Eingabetaste. Reagiert der Server mit einer Fehlermeldung, vergleichen Sie noch einmal die Variable mit dem Dateinamen auf dem Server.
Eine andere Fehlerquelle hängt mit Sicherheitseinschränkungen von Javascript im Browser zusammen: Das Request-Objekt darf nur mit demjenigen Server Kontakt aufnehmen, von dem auch die ursprüngliche HTML-Seite stammt. Weichen die Server-Adressen voneinander ab, meldet der Browser mit “Permission denied” die Verletzung der Sicherheitsrichtlinien.
Bei der Fehlersuche in AJAX-Anwendungen hat sich die Firefox-Extension Firebug als besonders hilfreich erwiesen [2]. Sie zeigt nicht nur Javascript-Fehler an, sondern auf Wunsch auch jeden einzelnen XMLHttpRequest mit Header-Feldern und Antwort-Codes.
Mit Daten
Ganz im Sinne der AJAX-Erfinder ist das obige Beispiel nicht. Serveranfragen im Hintergrund sollen natürlich vor allem dazu dienen, dynamische Inhalte die aktuelle Webseite zu integrieren. Das PHP-Skript in Listing 3 soll dafür den Test-Service realisieren. Es gibt bei jeder Anfrage eine zufällig Zahl zwischen 1 und 100 aus.
Listing 3
<? srand(time()); $random = (rand()%100); print $random; ?>
Haben Sie es unter dem Namen random.php im gleichen Verzeichnis auf dem Server gespeichert wie die anderen Dateien, müssen Sie die Variable url in ajax.js entsprechend ändern. Die entsprechende Zeile lautet dann:
var url = "http://localhost/~oli? ver/ajax/random.php";
Damit der Browser den geänderten Javascript-Code lädt, müssen Sie die ganze Seite mit dem Reload-Button neu laden. Klicken Sie auf den Link, zeigen die Dialogfenster wieder den jeweiligen Status des Request-Objekts.
An die gelieferten Server-Daten können Sie naturgemäß erst gelangen, wenn die Übertragung abgeschlossen ist, also im Zustand 4. Der Callback-Handler prüft also am besten bei jeder Zustandsänderung, ob dieser Endzustand schon erreicht ist, und verarbeitet erst am Ende die Nutzdaten.
Auslesen lässt er sich über die Variable readyState des Request-Objekts. Die Nutzdaten liefert das Feld responseText in ASCII-Textform. Die Funktion checkResult() sieht damit so aus, wie in Listing 4 zu sehen.
Listing 4
function checkResult()
{
if (request.readyState == 4) {
alert("Antwort: " + request.responseText);
}
}
Wenn Sie die Seite im Browser neu laden und auf den Link klicken, gibt nun ein Dialogfenster die vom Server zufällig erzeugte Zahl aus.
Die Webseite verändern
Nun haben Sie zwei der drei Schritte zur AJAX-Anwendung schon hinter sich: mit einem Request-Objekt eine Anfrage an den Server schicken und irgendwann die Antwort empfangen und verarbeiten. Bleibt noch die Aktualisierung der Webseite selbst. Schließlich sollen die Nutzdaten an der dafür vorgesehenen Stelle optisch ansprechend auftauchen und nicht nur in Form aufspringender Dialogboxen.
Auch diese Aufgabe übernimmt Javascript-Code, der auf verschiedene Weise Inhalt und Struktur der HTML-Seite verarbeiten kann. Browserintern repräsentiert das so genannte Document Object Model (DOM) den Aufbau jeder Seite (Abbildung 3). Dieser baumartige Aufbau jedes Dokuments ermöglicht es, in Javascript jedes beliebige HTML-Element zu referenzieren, auszulesen und zu verändern. Eigener Code kann in den Baum auch Elemente einbauen, die dann in der HTML-Seite neu erscheinen. Den Elementenbaum beliebiger Seiten können Sie sich in Firefox mit Tools | DOM Inspector ansehen (Abbildung 3).

Tools | DOM Inspector können Sie sich in Firefox das Document Object Model von HTML-Seiten anzeigen lassen.” width=”300″ height=”216″ />
Tools | DOM Inspector können Sie sich in Firefox das Document Object Model von HTML-Seiten anzeigen lassen.Fürs erste soll es genügen, ein bestehendes Element so zu verändern, dass es das Ergebnis der AJAX-Anfrage anzeigt. Besonders einfach geht das, wenn das zu verändernde Element eine eindeutige ID trägt, über die es sich in Javascript ansprechen lässt. In der HTML-Datei aus Listing 1 ist dazu das Span-Element mit der ID random vorgesehen.
Die Javascript-Funktion getElementById() des Gesamtdokuments liefert darüber bequem eine Referenz auf das HTML-Element. Der dann folgende Befehl setzt dessen Attribut innerHTML auf den erhaltenen Zufallswert.
var randomDiv = document.getElem?
entById("random");
randomDiv.innerHTML = request.re?
sponseText;
Schreiben Sie diese beiden Zeilen statt der alert-Funktion in die obige Version von checkResult(), ist die AJAX-Anwendung komplett: Der Javascript-Code schreibt das Ergebnis direkt in die HTML-Seite, statt sie komplett neu zu laden.
Inkompatibilitäten
Soweit die Theorie. Doch wie so häufig bei der Entwicklung von Webanwendungen sieht die Praxis etwas anders aus. Jeder Browser kocht sein eigenes Süppchen, und so muss der AJAX-Programmierer, versuchen mit diesen Eigenheiten zurecht zu kommen.
Los geht es mit dem Internet-Explorer, dessen aktuelle Versionen das XML-Request-Objekt nicht implementieren – zumindest nicht so, dass der Aufruf von XMLHttpRequest() zum gewünschten Ergebnis führt. Bei Microsoft gilt es dafür ein entsprechendes ActiveX-Objekt zu erzeugen, das sich glücklicherweise sonst so verhält wie die hier beschriebenen Request-Objekte. Tatsächlich ist sogar noch eine weitere Variante nötig, denn verschiedene Versionen des Internet Explorer erfordern unterschiedliche Syntax.
Weitere Problemkinder sind der KDE-Konqueror und der Apple-Browser Safari, denen manche Javascript-Konstrukte zur Manipulation des DOM-Baumes Schwierigkeiten bereitet. So funktioniert bei ihnen nicht die beschriebene Vorgehensweise, über die Dokumentenfunktion getElementById() an das zu verändernde Element zu gelangen. Das hier vorgestellte AJAX-Beispiel finden Sie noch einmal vollständig und mit allen Browser-Workarounds online unter [3].
Die Funktion checkResult() des Listings demonstriert außerdem, wie man die Interaktion noch dynamischer gestalten kann. Wie bereits in der letzten Variante setzt es das Span-Element nur auf das Ergebnis, wenn die Anfrage abgeschlossen ist (Zustand 4). Bei allen anderen Zustandsänderungen, die ja schon beim Aufbau der Verbindung beginnen, ändert es den Text auf Lade.., sodass der Benutzer sofort ein Feedback darüber erhält, dass etwas passiert.
Hilfe im Netz
Wie man sieht, erfordern AJAX-Webanwendungen etwas mehr Programmieraufwand als konventionelle Webseiten. Das beginnt schon beim Design: Nicht jede Website ist auch dafür geeignet, “ajaxifiziert” zu werden. Gute Planung ist deshalb noch wichtiger als bei der klassischen Webentwicklung. Schließlich muss für jeden AJAX-Abschnitt in einer Seite ein entsprechendes Skript auf dem Server bereitstehen. Außerdem benötigt der Javascript-Code jeder AJAX-Anwendung genaue Kenntnis über den Aufbau der Seiten. Cascading Stylesheets (CSS) verhelfen hier zu besserer Struktur, vergrößern aber die Anzahl an Dateien noch einmal.
Hilfreich sind die zahlreichen Javascript- und AJAX-Bibliotheken im Internet. So kapselt etwa Sajax [4] AJAX-Anfragen und die Verarbeitung der Antworten, damit Sie sich nicht mehr um Browser-Inkompatibilitäten und Ähnliches kümmern müssen. Mehr Komfort bieten beispielsweise Rico [5] oder die Yahoo User Interface Library (YUI) [6], die beide über die AJAX-Kommunikation hinaus auch noch eine Menge Funktionen für den Aufbau dynamischer HTML-Oberflächen mitbringen.
Infos
[1] AJAX: A New Approach to Web Applications: http://adaptivepath.com/publications/essays/archives/000385.php
[2] Firebug: http://www.joehewitt.com/software/firebug
[3] Listing online: http://www.linux-user.de/Downloads/2006/10/ajax
[4] Sajax: http://www.modernmethod.com/sajax
[5] Rico: http://openrico.org
[6] YUI: http://sourceforge.net/projects/yui






