AJAX – Tutorial
Transcription
AJAX – Tutorial
AJAX – Tutorial Das Wort Ajax ist ein regelrechtes Buzzword im Internet in den letzten Monaten, doch was steckt eigentlich hinter Ajax? Ajax ist die Abkürzung für: Asyncronous JavaScript and XML Ajax stellt eine Kombination aus länger existierenden Technologien da. JavaScript wird benutzt um im Browser des Client eine Anfrage zum Server zu stellen. Wenn diese Anfrage vom Server bearbeitet wurde, wird eine Funktion beim Client ausgeführt. Die Nachrichten die der Server verschickt, sind hierbei oft in XML codiert. Die Codierung in XML ist jedoch nicht zwingen, es kann auch eine Codierung als simpler Text erfolgen. XML bietet sich aber an um einen standardisierten Mechanismus zum parsen von Daten zu haben. Wie oben bereits erwähnt, führt der Server etwas aus und sendet eine Antwort als XML Dokument. Die Implementierung auf der Serverseite kann in einer beliebigen Programmier oder Skriptsprache realisiert werden. In diesem Tutorial und den Schaubildern verwende ich jedoch PHP als serverseitige Skriptsprache. Da die Anforderung vom Browser des Benutzers über JavaScript ausgelöst wird und mit JavaScript auch die Verarbeitung der Antwort erfolgt, ist kein Reload der Webseite notwendig. In modernen Webandwendungen wird diese Technologie gerne benutzt, um ein ähnliche Verhalten der Anwendung wie bei einer herkömlichen Desktopanwendung zu realisieren. Da ein gewisser Teil des Codes von Ajax Anwendungen immer ähnlich ist, gibt es im Internet einige Frameworks die die Programmierung von Ajax Anwendungen erleichtern wollen. Der Aufbau des ersten Ajax Programms Wir sollten uns nun erstmal die Zeit nehmen dieses erste Ajax Programm zu analysieren. Der grobe Aufbau sieht erstmal so aus: 1. Es gibt ein normales HTML Dokument mit Inline JavaScript Code. 2. Im Body des HTML Dokuments befindet sich ein div Container. Dieser Container hat die Id "eins". 3. In diesem Container befindet sich ein Button. (Anmerkung: kein Submit). Dieser Button ruft beim onclick Event die JavaScript Funktion doIt(); aus. 4. In der JavaScript Funktion doIt() wird zunächst das XMLHttpRequest Objekt erzeugt. 5. Mit diesem Request Objekt wird ein GET Request an die Url localhost/ajaxtutorial/eins/test.txt erzeugt. 6. Wenn das Request abgeschlossen ist wird eine Funktion aufgerufen. Diese wird hier als "anonyme"JavaScript Funktion mit function erzeugt. 7. In der "anonymen" CallBack Funktion wird der HTML Inhalt des Element mit der Id "eins" mit dem Inhalt des Response gefüllt. In diesem Fall wird also der Text "Hallo Welt" in den div Container geschrieben. Erzeugen des Ajax Request Objekts try{ req = new XMLHttpRequest(); } catch (e){ try{ req = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e){ try{ req = new ActiveXObject("Microsoft.XMLHTTP"); } catch (failed){ req = null; } } } In diesem Abschnitt wird das XMLHttpRequest Objekt angelegt. Seit der Version 7 ist dieses auch im Internet Explorer von Microsoft verfügbar. Vorher in der Version 5 und 6 gab es im IE dieses Objekt nicht, es gab jedoch ActiveXObject("Msxml2.XMLHTTP"); bzw. ActiveXObject("Microsoft.XMLHTTP"); die die gleiche Funktionalität über sogar gleichnamige Methoden bereitstellt. Aus Gründen der Kompatibilität zu diesen Versionen sollte man also diese Struktur verwenden. Das bedeutet beim IE 5 und 6 dass mit "new XMLHttpRequest();" bewusst eine Exception ausgelöst wird und im catch Block dann für den IE das Objekt angelegt wird. Unter folgender Url ist eine Spezifikation des XMLHttpRequest Objekts des W3C zu finden: http://www.w3.org/TR/XMLHttpRequest/ Auslösen eines asyncronen Requests req.open("GET", 'http://localhost/ajax-tutorial/eins/test.txt', true); Über die Methode open wird ein neuer Request erzeugt. Diese Methode hat folgende Parameter: • "GET" es handelt sich um einen HTTP GET Request, dazu später mehr. • An die Url "http://localhost/ajax-tutorial/eins/test.txt" soll der Aufruf gerichtet sein. Standardmässig ist beim Firefox z.b. nur ein Aufruf einer Adresse möglich die sich unterhalb der gleichen Url wie das Aufrufende Skript befindet. • "true" Dieser Parameter sagt, dass dieser Request asyncron ausgeführt werden soll. Definition einer Callback Funktion req.onreadystatechange = function(){ switch(req.readyState) { case 4: if(req.status!=200) { alert("Fehler:"+req.status); }else{ alert(req.responseText); //schreibe die antwort in den div container mit der id content document.getElementById('eins').innerHTML = '<strong>'+ req.responseText +'</strong>'; } break; default: return false; break; } }; Mit dem Attribut onreadystatechange wird eine Funktion festgelegt, die aufgerufen wird, wenn der request seinen readyState (abschlussStatus) ändert, z.b. wenn er erfolgreich abgeschlossen wurde. In diesem Fall wird mit function(){} eine anonyme Funktion erstellt. Zunächste wird in dieser Funktion der readyState geprüft ob er den gewünschten Wert 4 hat. Laut der W3C spezifikation gibt es 5 Stati: http://www.w3.org/TR/XMLHttpRequest/#xmlhttprequest-members Innerhalb des Falls 4 (abgeschlossener Transfer) wird nun geprüft ob der HTTP Statuscode den Wert 200 hat. 200 steht für eine Erfolgreiche Übertragung. Die HTTP Statuscodes findet man ebefalls auch beim W3C: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html Wenn alles erfolgreich gelaufen ist wird das Resultat der Abfrage (req.responseText) in das Element mit der id "eins" geschrieben. Header und Daten senden req.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); req.send(null); In diesem Bereich werden Felder des HTTP Headers gesetzt. Da keine Daten gesendet werden, ist auch bei send nichts zum senden vorhanden. Der HTML Inhalt <body> <div id="eins" style="width: 80%; height: 80%; border: dashed 1px;"> <input type="button" onclick="doIt();" value="Mach was!"/> </div> </body> Im body des HTML Dokuments befindet sich lediglich ein div Container, in diesem Div Container befindet sich ein Button, der die JavaScript Funktion doIt(); bei einem Klick ausführt. XML und DOM ein Beispiel mit GET In einem zweiten einfachen Beispiel möchte ich kurz auf die Verwendung von DOM eingehen. In diesem Beispiel soll folgende Funktionaltät realisiert werden: • Der Benutzer kann ein englisches Wort eingeben. • Der Browser übermittelt das Wort asynchron über Ajax zum Webserver, nach der Eingabe. Diese übermittlung wird mit einem GET Request gelöst, weil es nur ein Wort sein soll. Ajax Übersetzung in Action • Der Webserver schaut beim Babelfish Webservice per Soap nach Übersetzungen für dieses Wort in deutsch und französisch. Nachdem der Webserver eine Antwort erhalten hat übermittelt er ein XML Dokument mit den Übersetzungen an den Client. • Der Client wertet dieses XML Dokument mit DOM aus und schreibt die Werte in die passenden Formularfelder. Um den Quelltext so einfach wie Möglich zu halten wird auf unnötige Designelemente verzichtet. Das JavaScript benutze ich als Inline Code im HTML Dokument. Bei einer ernsthaften Implementierung sollte hierfür natürlich eine externe Datei verwendet werden. Das gleiche gilt für den CSS code. Die Realisierung auf der Serverseite erfolgt mit PHP5, da hier der SoapClient relativ einfach genutzt werden kann. Es dauert etwas länger bist eine Antwort erscheint, dabei muss man aber auch beachten was hinter der Kulisse passiert: • • • • • Anfrage via Ajax. Der Webserver läd eine WSDL Datei die den Webservice beschreibt. Auf dem Webserver abfrage eines Webservice via Soap. zurücksenden der Antwort. parsen und schreiben der Ergebnisse. Alle diese Vorgänge brauchen etwas Zeit und ist abhängig von der Netzanbinung der beteiligen Server. Ich denke aber das man hieran sehen kann was mit Ajax möglich ist. Beispiel: Server, Zugriff auf Babelfish via Soap Der in PHP geschriebene Server halt folgenden einfachen Aufbau: <?php header("Content-Type: text/xml"); $english = mysql_escape_string($_REQUEST['translate']); $trans = new SoapClient("http://www.xmethods.net/sd/2001/". "BabelFishService.wsdl"); try{ $german = $trans->BabelFish("en_de",$english); $french = $trans->BabelFish("en_fr",$english); } catch(SoapFault $e){ $english = "not found"; $german = "not found"; $french = "not found"; } echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>"; ?> <translation> <english><?php echo $english; ?></english> <german> <?php echo $german; ?></german> <french> <?php echo $french; ?></french> </translation> Beispiel: Die in XML codierte Übersetzung als Antwort Die Übersetzung des Strings "car" würde zum Beispiel folgendes XML Dokument als Antwort generieren: <translation> <english>car</english> <german> Auto </german> <french> voiture </french> </translation> Das Programm zur Übersetzung ist nun geschrieben. Im Vergleich zum ersten Beispiel hat sich garnicht so viel geändert. Im nächsten Abschnitt ist eine detailierte Analyse der Bereiche zu finden die sich geändert haben. Analyse des Beispiels Das die Funktion, die beim beenden des Requests ausgeführt wird diesmal etwas grösser geworden ist wurde diese in handleTranslation ausgelagert und der Name der Funktion bei onreadystatechange übergeben. Verarbeitung der Antwort mittels DOM in handleTranslation Da die Antwort XML kodiert ist erfolgt die Auswertung mittels DOM: //felder des formulars german_field = document.getElementById("german"); french_field = document.getElementById("french"); //antwort des servers xml = req.responseXML; german_resp = xml.getElementsByTagName("german")[0]; french_resp = xml.getElementsByTagName("french")[0]; //schreiben des ergebnisses german_field.value = german_resp.firstChild.nodeValue; french_field.value = french_resp.firstChild.nodeValue; In den ersten drei Zeilen wird lediglich das Formular Feld, in das später geschrieben werden soll in einer Variable gespeichert. In den nächsten drei Zeilen wird mit "req.responseXML" die XML antwort gelesen. Es wird jeweiles der Knoten mit dem Tag german und french zwischengespeichert. In den danach folgenden drei Zeilen wird das Ergebnis innerhalb dieser Tags in die Formularfelder geschrieben. So steht zum Schluss die Übersetzung in den dafür vorgesehenen Feldern. Übermittlung via GET In diesem Beispiel erfolgt die Übermittlung mit einem HTTP GET Request. Folgende stelle im Code ist dafür intressant: //anfrage erstellen (GET, url ist localhost, //request ist asynchron var url = 'http://localhost/ajax-tutorial/zwei/ajax.php?translate='+ document.getElementById('myword').value; req.open("GET", url, true); In der Variable "url" wird zunächst die Url zusammengebaut in dem das zu übersetzende Wort aus dem entsprechenden Textfeld ausgelesen wird und an die Url angehängt wird. Für das Beispiel mit dem Auto hätte die Url also folgenden Wert: "http://localhost/ajax-tutorial/zwei/ajax.php?translation=car" Muss ich XML benutzen? Wie man an diesem Beispiel sieht, hat XML einige Vor und Nachteile. Zunächst einmal die Vorteile: • XML ist weit verbreitet eine Verarbeitung des XML Dokuments ist in allen Programmiersprachen meisst mit eingenen Parsern möglich. • Wenn man DOM beherrscht ist eine Verarbeitung einfach möglich. • XML liefert eine Möglichkeit der validiering eines Dokuments quasi mit. XML bringt aber auch ein paar Nachteile mit sich: • Die Dokumente die zurück geschickt haben, enthalten viel an Drumherum (Overhead) aber nur wenig Nutzbare Daten. • Mit XML kommt zu JavaSkript und der serverseitigen Programmiersprache eine weitere Technologie hinzu die man beherrschen muss. • Sich in DOM einzuarbeiten für ein paar kleine Projekte kann u.U zu aufwändig sein. Aus den oben genannten Gründen gibt es JSON. JSON ermöglicht es auf dem Server Datenstrukturen wie z.B. einen Array in das JSON Format zu serialisieren. Im Client JavaScript kann diese serialisierte Struktur wieder zusammengebaut (deserialisiert) werden und genutzt werden. Quelle: http://www.admin-wissen.de/