mozilla
Ihre Suchergebnisse

    Einführung

    Dieser Artikel führt in die Grundlagen von AJAX ein und beschreibt zwei einfache und praktische Beispiele, die einen ersten Einblick liefern.

    Was ist AJAX?

    AJAX steht für »Asynchronous JavaScript and XML«. Grob gesagt ist es die Verwendung des nicht standardisierten XMLHttpRequest Objekts zur Kommunikation mit Server-seitigen Skripten. Es können sowohl Daten gesendet als auch empfangen werden und das in den unterschiedlichsten Formaten: XML, HTML und sogar Textdateien. Die ansprechendste Eigenschaft ist jedoch das »asynchronous« in AJAX, was bedeutet, dass die Operationen ohne die Seite neu zu laden ausgeführt werden können. Das erlaubt einem, Stückchen einer Seite zu aktualisieren, die auf Benutzerereignisse reagieren.

    Mit den zwei erwähnten Techniken kann man

    • Requests an den Server absetzen, ohne die Seite neu laden zu müssen
    • XML-Dokumente parsen und bearbeiten

    Schritt 1 – Wie mache ich einen HTTP-Request

    Um einen HTTP-Request mittels JavaScript an einen Server absetzen zu können, benötigt man eine Instanz einer Klasse, welche diese Funktionalität bietet. Solch eine Klasse, genannt XMLHTTP, wurde ursprünglich im Internet Explorer als ein ActiveX-Objekt eingeführt. Später implementierten Mozilla, Safari und andere Browser eine Klasse namens XMLHttpRequest, welche die Methoden und Eigenschaften des originalen ActiveX-Objektes von Microsoft unterstützt.

    Um nun eine browserübergreifende Instanz der benötigten Klasse zu erzeugen, kann man folgendes tun:

    if (window.XMLHttpRequest) { // Mozilla, Safari, ...
        http_request = new XMLHttpRequest();
    } else if (window.ActiveXObject) { // IE
        http_request = new ActiveXObject("Microsoft.XMLHTTP");
    }
    

    (Zur Veranschaulichung ist der im obigen Beispiel dargestellte Code zur Erzeugung einer XMLHTTP-Instanz vereinfacht dargestellt. Für ein wirklichkeitsgetreueres Beispiel sei auf Schritt 3 verwiesen.)

    Einige Versionen einiger Mozilla-basierter Browser werden nicht korrekt arbeiten, wenn die Antwort des Servers keinen XML mime-type im Header hat. Um dem entgegenzuwirken, kann man einen zusätzlichen Methodenaufruf absetzen, um den vom Server gesendeten Header zu überschreiben - für den Fall, dass dessen mime-type nicht text/xml lautet.

    http_request = new XMLHttpRequest();
    http_request.overrideMimeType('text/xml');
    

    Im nächsten Schritt entscheidet man, was zu tun ist, nachdem man vom Server eine Antwort zu dem abgesetzten Request bekommen hat. An dieser Stelle muss man dem HTTP Request-Objekt lediglich mitteilen, welche JavaScript-Funktion die Antwort abarbeiten soll. Dies erreicht man, indem man die onreadystatechange-Eigenschaft des Objektes genauso nennt wie die JavaScript-Funktion, welche man benutzen möchte, ungefähr so:

    http_request.onreadystatechange = nameDerFunktion;

    Es ist zu beachten, dass nach dem Funktionsnamen keine Klammern auftauchen und der Funktion keine Parameter übergeben werden. Des weiteren kann man anstelle der Angabe eines Funktionsnamens die Funktion "on the fly" definieren, etwa so:

    http_request.onreadystatechange = function(){
        // mach etwas
    };
    

    Nachdem wir beschrieben haben was mit der empfangenen Antwort geschehen soll, muss der Request abgesetzt werden. Dazu ruft man die Methoden open() und send() der HTTP-Request Klasse auf, etwa so:

    http_request.open('GET', 'http://www.beispiel.org/eine.datei', true);
    http_request.send(null);
    
    • Der erste Parameter des Aufrufs der Methode open() ist die HTTP-Request-Methode - GET, POST, HEAD oder eine beliebige andere Methode, welche eingesetzt werden soll und welche vom verwendeten Server unterstützt wird. Die Methode sollte nach dem HTTP-Standard groß geschrieben werden, da andernfalls einige Browser (z.B. Firefox) die Anfrage nicht verarbeiten. Für mehr Informationen zu den möglichen HTTP-Request-Methoden sei auf die W3C Spezifikationen verwiesen.
    • Der zweite Parameter ist die URL der angeforderten Seite. Aus Sicherheitsgründen können keine Seiten auf 3rd-party Domains angefordert werden. Es muss sichergestellt werden, dass der exakte Domainname auf allen Seiten benutzt wird; andernfalls bekommt man einen 'permission denied'-Fehler beim Aufruf von open(). Ein beliebter Fallstrick ist der Aufruf einer Seite mittels 'domain.tld', wobei die gewünschte Seite jedoch 'www.domain.tld' lautet.
    • Der dritte Parameter gibt an, ob der Request asynchron sein soll. Wenn er auf true gesetzt ist, wird die JavaScript-Funktion weiter ausgeführt, während die Antwort des Servers noch aussteht. Dies ist das A in AJAX.

    Der Parameter der send()-Methode können beliebige Daten sein, die an den Server per POST gesendet werden sollen. Die Daten sollten in Form einer Suchanfrage formuliert sein, etwa so:

    name=wert&anderername=andererwert&so=weiter

    Bei der Übergabe der Daten per POST ist zu beachten, dass der MIME-Typ der Anfrage wie folgt angepasst werden muss:

    http_request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    

    Andernfalls wird der Server die per POST übergebenen Daten ignorieren. Wichtig dabei ist, dass die 'setRequestHeader'-function nach der 'open'-function aufgerufen wird, da es sonst zu einem Fehler kommt.

    Schritt 2 – Verarbeiten der Antwort des Servers

    Zur Erinnerung: beim Abschicken des Requests wurde der Name einer JavaScript-Funktion mitgegeben, welche die Antwort abarbeiten soll.

    http_request.onreadystatechange = nameDerFunktion;

    Schauen wir mal, was diese Funktion tun sollte. Zuerst muss die Funktion den Status des Requests abfragen. Hat dieser den Wert 4, bedeutet das, dass die Antwort des Servers vollständig empfangen wurde und dass sie nun bearbeitet werden kann.

    if (http_request.readyState == 4) {
        // alles in Ordnung, Antwort wurde empfangen
    } else {
        // noch nicht bereit
    }
    

    Die komplette Liste der readyState Werte sieht wie folgt aus:

    • 0 (nicht initialisiert)
    • 1 (lade)
    • 2 (geladen)
    • 3 (interaktiv)
    • 4 (vollständig)

    (Quelle)

    Als nächstes muss die Antwort des HTTP-Servers geprüft werden. Alle möglichen Codes sind auf der W3C-Seite aufgelistet. Für unsere Zwecke interessiert nur der Antwortcode 200 OK.

    if (http_request.status == 200) {
        // perfekt!
    } else {
        // die Anfrage enthielt Fehler;
        // die Antwort war z.B. 404 (nicht gefunden)
        // oder 500 (interner Server-Fehler)
    }
    

    Nachdem nun der Status des Requests und der HTTP-Status geprüft wurden, kann man mit den vom Server gesendeten Daten anstellen, was man möchte. Für den Zugriff auf die Daten gibt es zwei Möglichkeiten:

    • http_request.responseText – gibt die Antwort des Servers als einen Textstring zurück
    • http_request.responseXML – gibt die Antwort des Servers als ein XMLDocument-Objekt zurück, welches man mittels der JavaScript DOM-Funktionen verarbeiten kann

    Schritt 3 – Ein einfaches Beispiel

    Jetzt führen wir alles zusammen und machen einen einfachen HTTP-Request. Per JavaScript wird ein HTML-Dokument namens test.html angefordert, welches den Text "Ich bin ein Test." enthält. Anschließend geben wir per alert() den Inhalt dieser Datei aus.

    <script type="text/javascript" language="javascript">
    
        var http_request = false;
    
        function macheRequest(url) {
    
            http_request = false;
    
            if (window.XMLHttpRequest) { // Mozilla, Safari,...
                http_request = new XMLHttpRequest();
                if (http_request.overrideMimeType) {
                    http_request.overrideMimeType('text/xml');
                    // zu dieser Zeile siehe weiter unten
                }
            } else if (window.ActiveXObject) { // IE
                try {
                    http_request = new ActiveXObject("Msxml2.XMLHTTP");
                } catch (e) {
                    try {
                        http_request = new ActiveXObject("Microsoft.XMLHTTP");
                    } catch (e) {}
                }
            }
    
            if (!http_request) {
                alert('Ende :( Kann keine XMLHTTP-Instanz erzeugen');
                return false;
            }
            http_request.onreadystatechange = alertInhalt;
            http_request.open('GET', url, true);
            http_request.send(null);
    
        }
    
        function alertInhalt() {
    
            if (http_request.readyState == 4) {
                if (http_request.status == 200) {
                    alert(http_request.responseText);
                } else {
                    alert('Bei dem Request ist ein Problem aufgetreten.');
                }
            }
    
        }
    </script>
    <span
        style="cursor: pointer; text-decoration: underline; color: blue"
        onclick="macheRequest('test.html')">Einen Request absetzen
    </span>
    

    Erklärung zu diesem Beispiel:

    • Der Benutzer klickt im Browser auf den Link „Einen Request absetzen“;
    • Dies ruft die Methode macheRequest() mit einem Parameter – der Name einer HTML-Datei im gleichen Verzeichnis (test.html)
    • Der Request wird abgesetzt und anschließend (onreadystatechange) wird alertInhalt() ausgeführt;
    • alertInhalt() prüft, ob die Antwort empfangen wurde und ob sie OK (Status 200) ist und gibt anschließend per alert() den Inhalt der Datei test.html aus.

    Hinweis: Die Zeile httpRequest.overrideMimeType('text/xml'); weiter oben führt in der JavaScript Konsole in Firefox 1.5 oder später zu Fehlern, wie im Bug Bug 311724 beschrieben, tritt dieser Fehler auf, wenn die angeforderte Seite kein valides XML ist (z.B. wenn die Seite Fließtext ist).

    Hinweis 2: Wird eine Anfrage gesendet, die XML zurück gibt, müssen - anders als bei statischen XML Dateien - Response Headers gesetzt werden, damit die Seite auch im Internet Explorer funktioniert. Wird kein Header: Content-Type: application/xml gesetzt, wird der IE einen JavaScript Fehler 'Object Expected' ausgeworfen, nachdem versucht wurde Zugang zum XML Element zu erlangen. Wird der Header Cache-Control: no-cache  nicht gesetzt, speichert der Browser die Antwort und wird keine Request neu versenden, sodass das Debugging zur Herausforderung wird.

    Hinweis 3: Wenn die httpRequest Variable global verwendet wird, überschreiben sich eventuell Funktionsaufrufe wie macheRequest() gegenseitig. Wird die httpRequest Variable lokal verwendet und durch die alertInhalt() Funktion eingesetzt, verhindert dies das gegenseitige Überschreiben.

    Hinweis 4: Um die Callback-Funktion onreadystatechange zu registrieren, können keine Argumente übergeben werden. Der folgende Code funktioniert daher nicht:

    httpRequest.onreadystatechange = alertInhalt(httpRequest); // (funktioniert nicht)
    

    Um die Funktion erfolgreich zu registrieren, kann entweder eine anonyme Funktion verwendet werden oder httpRequest als eine globale Variable eingesetzt werden. So wie im folgenden Beispiel:

    httpRequest.onreadystatechange = function() { alertInhalt(httpRequest); };  //1 (Simultane Anfrage)
    httpRequest.onreadystatechange = alertInhalt;  //2 (globale Variable)
    

    Methode 1 sorgt für mehrere Anfragen, die gleichzeitig ausgeführt werden, während Method 2 verwendet wird, wenn httpRequest als globale Variable ist.


    Hinweis 5: Wenn es einen Kommunikationsfehler gibt (z.B. Unerreichbarkeit des Webservers), wird eine Exception in der onreadystatechange Methode ausgeworfen, wenn versucht wird die .status Variable zu erreichen. Es sollte sichergestellt werden, dass die if...then Aussage sich innerhalb von try...catch befindet. (Siehe: Bug 238559).

    function alertInhalt(httpRequest) {
    
            try {
                if (httpRequest.readyState == 4) {
                    if (httpRequest.status == 200) {
                        alert(httpRequest.responseText);
                    } else {
                        alert('There was a problem with the request.');
                    }
                }
            }
            catch( e ) {
                alert('Caught Exception: ' + e.description);
            }
    
        }
    

    Schritt 4 – Verarbeiten der XML-Response

    Im vorhergehenden Beispiel wurde, nachdem die Antwort des HTTP-Requests empfangen wurde, die responseText-Eigenschaft des Request-Objektes benutzt, welche den Inhalt der Datei test.html enthielt. Nun versuchen wir einmal die responseXML-Eigenschaft.

    Zuerst erzeugen wir ein valides XML-Dokument, welches später angefordert wird. Das Dokument (test.xml) hat folgenden Inhalt:

    <?xml version="1.0" ?>
    <root>
        Ich bin ein Test.
    </root>
    

    Im Skript brauchen wir nur die Zeile mit macheRequest() wie folgt zu ändern:

    ...
    onclick="macheRequest('test.xml')">
    ...
    

    Danach muss man in alertInhalt() die Zeile alert(http_request.responseText); ersetzen durch:

    var xmldoc = http_request.responseXML;
    var root_node = xmldoc.getElementsByTagName('root').item(0);
    alert(root_node.firstChild.data);
    

    Jetzt werden DOM-Methoden benutzt, um Daten aus dem XML-Dokument zu lesen, welches als XMLDocument-Objekt mittels responseXML gelesen wurde. Die Datei test.xml kann man sich hier ansehen, das geänderte Test-Skript hier.

    Für weiterführende Informationen zu den DOM-Methoden sei auf das Dokument Mozillas DOM Implementierung verwiesen.

    Schlagwörter des Dokuments und Mitwirkende

    Schlagwörter: 
    Mitwirkende an dieser Seite: Diskostu, Takenbot, fscholz, Gerhard, Dundanox
    Zuletzt aktualisiert von: fscholz,