Blog der Heimetli Software AG

AJAX-Einführung

AJAX wird dazu benutzt, dynamische Webseiten zu erstellen. Dynamisch heisst in diesem Kontext, dass bei Aenderungen der Daten auf dem Server auch die angezeigten Daten auf der Webseite ändern, und zwar ohne dass die Seite neu geladen wird.

Dieser Post beschreibt so einfach wie möglich, wie AJAX funktioniert.

AJAX heisst eigentlich "Asynchronous JavaScript And XML", aber die Entwickler erkannten, dass XML nicht das beste Format für die Datenübertragung ist. Der Name ist geblieben, aber heute wird meist JSON als Datenformat benutzt.

Für diese Einführung habe ich das JSON zur Vereinfachung weggelassen. Der Browser kriegt den reinen Text mit dem aktuellen Status vom Server.

Voraussetzungen

Der Code wurde unter Raspbian 7.0 mit einem Apache 2.2.22 als Webserver auf dem Raspberry PI getestet. Er müsste aber portabel sein und auf jedem Unix oder Linux mit einem Webserver laufen.

Uebersicht

AJAX braucht Code auf dem Server und im Browser. Auf dem Server kann jede beliebige Sprache verwendet werden, während im Browser eigentlich nur JavaScript läuft.

Weil der Code auf dem Server sehr einfach ist, fangen wir mit dem Programm auf dem Server an.

Das Script auf dem Server

Wenn der Browser nach dem aktuellen Status verlangt, ruft der Webserver das folgende Script auf. Ich habe es in ein File namens gettime geschrieben.

#!/bin/bash
echo -en "Content-Type: text/plain\r\n\r\n"
echo -en "$(date '+%d.%m.%Y %H:%M:%S')"

Die erste Zeile definiert, dass das Script von der bash-Shell ausgeführt werden soll und bewirkt keine Ausgabe.

Die nächste Zeile gibt den Content-Type und zwei Leerzeilen aus. Diese Angabe braucht der Webserver. Er übernimmt den Content-Type und gibt ihn an den Browser weiter. Die beiden Leerzeilen zeigen das Ende des Headers an. Was folgt, ist der Content für den Browser.

Die dritte Zeile formatiert das Datum und gibt es aus. Der Webserver gibt den Text unverändert an den Browser weiter.

Damit das Script laufen kann, braucht es die entsprechenden Rechte. Die bekommt es durch den Befehl chmod:

chmod 755 gettime

Jetzt kann es durch beliebige User ausgeführt und gelesen werden. Beliebige User ist wichtig, weil es mit den Rechten des Webservers ausgeführt wird und nicht durch den aktuellen User.

Das Script muss natürlich dort liegen, wo es der Webserver auch findet. Bei meiner Installation ist das das Directory /usr/lib/cgi-bin. Dieses Directory ist für normale User nicht schreibbar, also brauchen wir sudo um es dorthin zu kopieren:

sudo cp gettime /usr/lib/cgi-bin

Der erste Schritt ist geschafft, wir können den ersten Test machen. Also Bowser auf, die Adresse vom Raspberry eintippen und /cgi-bin/gettime anhängen. Die Adresszeile im Browser müsste also etwa so aussehen:

http://192.168.1.20/cgi-bin/gettime

Wenn alles stimmt, zeigt der Browser eine Zeile an mit dem aktuellen Datum und der Uhrzeit.

Die HTML-Seite mit dem JavaScript

Um das Beispiel einfach zu halten, steht das JavaScript direkt in der HTML-Seite. Das ist selbstverständlich schlechter Stil, das JavaScript sollte in einem eigenen File liegen.

Wenn die Seite index.html heisst, wird sie vom Apache als Startseite ausgeliefert.

<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8">
  <meta name="author" content="P. Tellenbach">
  <title>AJAX Demo</title>
  <script type="text/javascript">
   var timer  = setInterval( pollServer, 1000 ) ;
   var active = -1 ;

   function pollServer()
   {
      try
      {
         var request = new XMLHttpRequest() ;

         if( request )
         {
            request.onreadystatechange = function()
            {
               if( request.readyState == 4 )
               {
                  if( request.status == 200 )
                  {
                     process( request.responseText ) ;
                  }
               }
            }

            request.open( "GET", "/cgi-bin/gettime", true ) ;
            request.send( null ) ;
         }
         else
         {
            alert( "XMLHttpRequest failed" ) ;

            clearInterval( timer ) ;
         }
      }
      catch( err )
      {
         alert( err.description ) ;

         clearInterval( timer ) ;
      }
   }

   function process( text )
   {
      var element = document.getElementById( "time" ) ;

      element.innerHTML = text ;
   }
  </script>
 </head>
 <body>
  <h1>AJAX Demo</h1>
  <p>Hier steht die Zeit vom Server: <span id="time"></span></p>
 </body>
</html>

Im HTML gibt es nichts Besonderes, ausser dem leeren span-Element mit der Id. Auf dieses Element greift das JavaScript zu und setzt die Zeit vom Server ein.

Der wichtigste Teil des JavaScripts mit Kommentaren:

/* Ein XMLHttpRequest wird erzeugt */
var request = new XMLHttpRequest() ;
/* Definiert was passiert wenn sich der Status des
 * XMLHttpRequests ändert
 */
request.onreadystatechange = function()
{
   /* Nur der Status 4 ist interessant. Er bedeutet
    * dass die Antwort vom Server eingetroffen ist
    */ 
   if( request.readyState == 4 )
   {
      /* Den Statuscode vom Server prüfen. 200 zeigt
       * an dass der Server die Seite erfolgreich
       * ausgeliefert hat
       */
      if( request.status == 200 )
      {
         /* Den empfangenen Text an process übergeben */
         process( request.responseText ) ;
      }
   }
}
/* Legt die Parameter für die Abfrage beim Server fest.
 * Weil das letzte Argument true ist, wird der Aufruf
 * asynchron durchgeführt. Das heisst, dass der Aufruf
 * zurückkommt bevor der Server antwortet
 */
request.open( "GET", "/cgi-bin/gettime", true ) ;
/* Abfrage beim Server starten */
request.send( null ) ;

Dieser Code sieht bei jeder AJAX-Seite ähnlich aus, denn die effektive Verarbeitung der der empfangenen Daten ist in die Funktion process ausgelagert.

function process( text )
{
   /* Hole das Element mit der angegebenen Id */
   var element = document.getElementById( "time" ) ;
   /* Setze den empfangenen Text ins Element ein */
   element.innerHTML = text ;
}

Fast fertig, es fehlt nur noch der periodische Aufruf der Abfrage. Das macht folgende Zeile:

var timer = setInterval( pollServer, 1000 ) ;

Auch die HTML-Seite muss lesbar für alle sein. Wenn es nicht schon per Default so ist, erreicht man das wieder mit chmod.

chmod 644 index.html

Als letztes muss die Seite ins Web-Directory kopiert werden:

sudo cp index.html /var/www

Fertig ! Browser auf und die Seite testen:

 http://192.168.1.20

Damit Sie nicht alles abtippen müssen, können Sie die Files hier herunterladen: gettime und index.html