Ajax kombiniert JavaScript, HTML, DHTML, DOM und XML, um die Programmierung interaktiver Webseiten zu erleichtern.
Ohne Ajax werden Benutzereingaben auf Webseiten üblicherweise als Request zum Server gesendet, es wird auf die Antwort vom Server gewartet und die HTML-Seite wird neu aufgebaut. Dies führt zu einem weniger flüssigen Arbeiten als mit Desktop-Anwendungen.
Bei Verwendung von Ajax erfolgt die Kommunikation nicht direkt vom HTML-Formular zum Server, sondern es wird JavaScript-Code dazwischen geschaltet und die Kommunikation erfolgt über ein XMLHttpRequest-Objekt, üblicherweise asynchron und über XML-Datenaustausch. Nach Absenden von Requests kann im Client weitergearbeitet werden. Wenn die Antwort vom Server eintrifft, ruft das XMLHttpRequest-Objekt eine Client-seitige Callback-Methode auf, die dann zum Beispiel Teile der Webseite aktualisieren kann.
Das XMLHttpRequest-Objekt ist in den meisten modernen Webbrowser-Versionen verfügbar (ab den Versionen: Microsoft Internet Explorer 5.0, Mozilla Firefox 1.0, Netscape 7.1, Apple Safari 1.2, Opera Mobile Browser 8.0).
Wenn Sie Probleme bei der Ausführung der JavaScripts haben, sollten Sie Debugging-Hilfen einschalten. Um das DOM-Modell besser zu verstehen ist der DOM Inspector hilfreich.
Mozilla Firefox
Um im Mozilla Firefox JavaScript-Fehlermeldungen angezeigt zu bekommen, geben Sie als URL-Adresse ein: 'javascript:'. Alternativ können Sie auch wählen: 'Extras' | 'JavaScript-Konsole'.
Um im Firefox JavaScript zu debuggen, installieren Sie den Venkman JavaScript Debugger von: http://www.mozilla.org/projects/venkman/.
Um den Firefox DOM Inspector zu benutzen, müssen Sie Firefox nicht in der Installationsart 'Standard', sondern 'Benutzerdefiniert' installieren und bei 'Komponenten auswählen' die 'Developer Tools' aktivieren. Anschließend können Sie den DOM Inspector aufrufen über 'Extras' | 'DOM Inspector'.
Microsoft Internet Explorer
Im Microsoft Internet Explorer stellen Sie unter
'Extras' | 'Internetoptionen...' | 'Erweitert' | 'Browsing' ein:
'Skriptdebugging deaktivieren' ausschalten und
'Skriptfehler anzeigen' einschalten.
Wenn Sie nicht nur Fehler im JavaScript angezeigt bekommen wollen, sondern auch durch den JavaScript-Code durchsteppen wollen, sollten Sie zusätzlich zu obiger Einstellung den Microsoft Script Debugger for Windows scd10en.exe downloaden und installieren.
Das JavaScript-Objekt "XMLHttpRequest" bildet den Kern von Ajax. Es folgt eine tabellarische Übersicht der wichtigsten Methoden und Attribute. Die Funktionsweise wird in den Beispielen in den nächsten Kapiteln verdeutlicht.
Weitere Erläuterungen finden Sie unter http://xulplanet.com/references/objref/XMLHttpRequest.html und http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/objects/obj_xmlhttprequest.asp.
Die wichtigsten Methoden von XMLHttpRequest | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
open( httpReqMeth, url, async ) open( httpReqMeth, url, async, usr, pwd ) |
| ||||||||||||||||||
send( postReq ) |
| ||||||||||||||||||
abort() | Bricht eine aktuell laufende Anfrage ab | ||||||||||||||||||
setRequestHeader( key, value ) | Fügt dem HTTP-Header ein Key-Value-Paar hinzu (z.B.: setRequestHeader('Content-Type','application/x-www-form-urlencoded');) | ||||||||||||||||||
getResponseHeader( key ) | HTTP-Header-Eintrag zum gegebenen Key | ||||||||||||||||||
getAllResponseHeaders() | Alle HTTP-Header-Einträge | ||||||||||||||||||
Die wichtigsten Attribute von XMLHttpRequest | |||||||||||||||||||
onreadystatechange | Enhält die Event-Handler-Callback-Methode, welche bei Zustandsänderungen des XMLHttpRequest-Objekts aufgerufen wird, z.B. wenn Antwort vom Server eintrifft | ||||||||||||||||||
readyState | Hierüber wird der Event-Handler-Callback-Methode der Status des XMLHttpRequest-Objekts übermittelt: 0 = uninitialized 1 = loading 2 = loaded 3 = interactive 4 = complete | ||||||||||||||||||
status | Der vom Server übermittelte
HTTP-Status, z.B.: 200 = OK 404 = Not Found | ||||||||||||||||||
statusText | der zum HTTP-Status passende Text | ||||||||||||||||||
responseText | Die Antwort des Servers als Text-String | ||||||||||||||||||
responseXML | Die Antwort des Servers im XML-Format als XMLDocument, welches über DOM-Methoden behandelt wird |
Das folgende Beispiel erfüllt keinen sinnvollen Zweck. Es zeigt lediglich den prinzipiellen Kommunikationsablauf.
Erzeugen Sie folgende HTML-Datei 'AjaxTest1.html':
<html> <head> <script language="JavaScript" type="text/javascript"> // Setzen Sie eine geeignete URL ein // (beachten Sie dazu die Hinweise im Text): // Z.B. http://checkip.dyndns.org // oder checkiptxt.jsp var url = "http://checkip.dyndns.org"; var req; function starteAjax() { try { if( window.XMLHttpRequest ) { req = new XMLHttpRequest(); } else if( window.ActiveXObject ) { req = new ActiveXObject( "Microsoft.XMLHTTP" ); } else { alert( "Ihr Webbrowser unterstuetzt leider kein Ajax!" ); } req.open( "GET", url, true ); req.onreadystatechange = meineCallbackFkt; req.send( null ); } catch( e ) { alert( "Fehler: " + e ); } } function meineCallbackFkt() { if( 4 == req.readyState ) { if( 200 != req.status ) { alert( "Fehler " + req.status + ": " + req.statusText ); } else { alert( req.responseText ); } } } </script> </head> <body onload="starteAjax()"> <h2>Mein erster Ajax-Test</h2> <noscript> <font color="red"><big><b>Bitte JavaScript einschalten!</b></big></font><br> </noscript> </body> </html>
Erläuterungen:
Microsoft Internet Explorer:
Falls Sie den Microsoft Internet Explorer 6 verwenden, können Sie diese HTML-Datei direkt ausführen.
Falls Sie die Meldung "Bitte JavaScript einschalten!" erhalten, müssen Sie
a) unter 'Extras' | 'Internetoptionen...' | 'Sicherheit' | 'Stufe anpassen...' 'ActiveX' erlauben und
b) eventuell auf den oberhalb der Webseitendarstellung erschienenen gelben Balken klicken und
'Geblockte Inhalte zulassen...' wählen.
Tragen Sie im HTML-Quelltext bei 'var url = "..."' verschiedene URLs zu kurzen Textdateien oder HTML-Seiten ein, z.B.: http://checkip.dyndns.org.
Andere Webbrowser (z.B. Mozilla Firefox 1.5):
Mit den meisten anderen Webbrowsern können Sie das Beispiel leider noch nicht ausführen,
da deren Sicherheitseinstellungen erwarten,
dass die HTML-Datei von der gleichen Webserver-Domain geladen wird wie der Dienst.
(Z.B. mit Firefox 1.5 erhalten Sie die Fehlermeldung:
"Die Erlaubnis für den Aufruf der Methode XMLHttpRequest.open wurde verweigert".)
Im nächsten Kapitel wird deshalb ein Dienst auf einem Webserver installiert.
Erzeugen Sie in Ihrem Tomcat-'webapps/ROOT'-Verzeichnis (z.B. D:\Tools\Tomcat\webapps\ROOT) das Unterverzeichnis 'ajax'. Erzeugen Sie im 'ajax'-Unterverzeichnis folgende JSP-Datei 'checkiptxt.jsp':
<%= request.getRemoteHost() %>
Erzeugen Sie in Ihrem Tomcat-'webapps/ROOT'-Verzeichnis das Unterverzeichnis 'ajax'. Erzeugen Sie im 'ajax'-Unterverzeichnis folgende HTML-Datei 'AjaxTest2.html':
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>AJAX</title> <meta http-equiv="content-type" content="text/html;charset=iso-8859-1"> <script language="JavaScript" type="text/javascript"> var url0 = "ajaxtest.jsp"; var req; function meinAjaxInit() { try { if( window.XMLHttpRequest ) { req = new XMLHttpRequest(); } else if( window.ActiveXObject ) { req = new ActiveXObject( "Microsoft.XMLHTTP" ); } else { alert( "Ihr Webbrowser unterstuetzt leider kein Ajax!" ); } if( req.overrideMimeType ) { req.overrideMimeType( 'text/xml' ); } } catch( e ) { alert( "Fehler: " + e ); } } function meinAjaxAufruf() { if( req ) { var zahlEingabe = document.getElementById( "zahlEingabe" ); var textEingabe = document.getElementById( "textEingabe" ); var url = url0 + "?zahl=" + escape( zahlEingabe.value ) + "&text=" + escape( textEingabe.value ); req.open( "GET", url, true ); req.onreadystatechange = meineCallbackFkt; req.send( null ); } } function meineCallbackFkt() { if( 4 == req.readyState ) { if( 200 != req.status ) { alert( "Fehler " + req.status + ": " + req.statusText ); } else { ergebnis = req.responseXML.documentElement; var zahlAusgabe = ergebnis.getElementsByTagName('zahl')[0].firstChild.data; var textAusgabe = ergebnis.getElementsByTagName('text')[0].firstChild.data; var ipAusgabe = ergebnis.getElementsByTagName('ip')[0].firstChild.data; document.getElementById("zahlAusgabe").value = zahlAusgabe; document.getElementById("textAusgabe").value = textAusgabe; document.getElementById("ipAusgabe").innerHTML = ipAusgabe; } } } </script> </head> <body onload="meinAjaxInit()"> <h2>Mein zweiter Ajax-Test</h2> <noscript> <font color="red"><big><b>Bitte JavaScript einschalten!</b></big></font><br> </noscript> <form action="#" method="GET" name="MeinFormular"> Zahl eingeben: <input type="text" name="zahlEingabe" id="zahlEingabe" onKeyUp="meinAjaxAufruf();"> <input type="text" name="zahlAusgabe" id="zahlAusgabe" readonly="true"> Quadrat<br> Text eingeben: <input type="text" name="textEingabe" id="textEingabe" onKeyUp="meinAjaxAufruf();"> <input type="text" name="textAusgabe" id="textAusgabe" readonly="true"> Sortiert<br> <br>IP-Adresse: <span id="ipAusgabe"></span> </form> </body> </html>
Erläuterungen:
Installieren Sie Java und Tomcat wie oben beschrieben und erzeugen Sie im bereits angelegten Tomcat-'webapps/ROOT/ajax'-Unterverzeichnis folgende JSP-Datei 'ajaxtest.jsp':
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <% response.setContentType("text/xml"); response.setHeader("Cache-Control", "no-cache"); String zahl = request.getParameter( "zahl" ); String text = request.getParameter( "text" ); if( null == zahl || 0 >= zahl.trim().length() ) { zahl = "-"; } else { try { long i = Long.parseLong( zahl ); zahl = "" + i * i; } catch( Exception ex ) {/*ok*/} } if( null == text || 0 >= text.trim().length() ) { text = "-"; } else { char[] c = text.toCharArray(); java.util.Arrays.sort( c ); text = new String( c ); } %> <MeinErgebnis> <zahl><%= zahl %></zahl> <text><%= text %></text> <ip><%= request.getRemoteHost() %></ip> </MeinErgebnis>
'ajaxtest.jsp' returniert eine XML-Datei. Überprüfen Sie dies (bei laufendem Tomcat) über den Aufruf von http://localhost:8080/ajax/ajaxtest.jsp und http://localhost:8080/ajax/ajaxtest.jsp?zahl=12&text=ajaxtext. Sie erhalten je nach Webbrowser in etwa Folgendes:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <MeinErgebnis> <zahl>144</zahl> <text>aaejttxx</text> <ip>127.0.0.1</ip> </MeinErgebnis>
Erzeugen Sie in Ihrem Tomcat-'webapps/ROOT'-Verzeichnis das Unterverzeichnis 'ajax'. Erzeugen Sie im 'ajax'-Unterverzeichnis folgende HTML-Datei 'AjaxTest3.html':
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>AJAX-Test: Eingabe-Autovervollständigung</title> <meta http-equiv="content-type" content="text/html;charset=iso-8859-1"> <style type="text/css"> body { font-family: sans-serif } a.auswahlzeile { color: black; text-decoration: none; display: block; width: 100%; } a.auswahlzeile:hover { background-color: #66FF66; } </style> <script language="JavaScript" type="text/javascript"> var req = null; var eingabetext = ""; var auswahlarray = new Array(); function meinAjaxInit() { try { if( window.XMLHttpRequest ) { req = new XMLHttpRequest(); } else if( window.ActiveXObject ) { req = new ActiveXObject( "Microsoft.XMLHTTP" ); } else { alert( "Ihr Webbrowser unterstuetzt leider kein Ajax!" ); } } catch( e ) { alert( "Fehler: " + e ); } } function meinAjaxAufruf( eingabe ) { meinAjaxInit(); if( req ) { eingabetext = eingabe; document.formular.eingabefeld.focus(); var url = "autovervollstaendigung.jsp?eingabe=" + escape( eingabetext ); req.open( "GET", url, true ); req.onreadystatechange = meineCallbackFkt; req.send( null ); } } function meineCallbackFkt() { if( 4 == req.readyState ) { if( 200 != req.status ) { alert( "Fehler " + req.status + ": " + req.statusText ); } else { var auswahlinhalt = ""; var text = req.responseText; if( text != "" ) { auswahlarray = text.split( ";" ); for( var idx in auswahlarray ) { auswahlinhalt += "<a href='javascript:meinMausklick(" + idx + ")' id='" + idx; auswahlinhalt += "' class='auswahlzeile' onmouseover='meinMausover("+idx+")'>"; auswahlinhalt += auswahlarray[idx] + "</a>"; } document.getElementById( "auswahlbox" ).innerHTML = auswahlinhalt; } if( auswahlinhalt != "" ) { document.getElementById( "auswahlbox" ).style.visibility = "visible"; } else { document.getElementById( "auswahlbox" ).style.visibility = "hidden"; } } } } function meinMausklick( idx ) { if( auswahlarray[idx] != null && auswahlarray[idx] != "" ) { var eingabefeld = document.formular.eingabefeld; eingabefeld.value = auswahlarray[idx]; eingabefeld.focus(); document.getElementById( "ergebnisanzeige" ).innerHTML = auswahlarray[idx]; document.getElementById( "auswahlbox" ).style.visibility = "hidden"; } } function meinMausover( idx ) { if( auswahlarray[idx] != null && auswahlarray[idx] != "" ) { var eingabefeld = document.formular.eingabefeld; var start = eingabetext.length; var laenge = auswahlarray[idx].length; eingabefeld.value = auswahlarray[idx]; if( eingabefeld.createTextRange ) { var Auswahl = eingabefeld.createTextRange(); Auswahl.moveStart( "character", start ); Auswahl.moveEnd( "character", laenge - start ); Auswahl.select(); } else if( eingabefeld.setSelectionRange ) { eingabefeld.setSelectionRange( start, laenge ); } eingabefeld.focus(); } } </script> </head> <body> <h2>Mein Ajax-Test mit Eingabe-Autovervollständigung</h2> <noscript> <font color="red"><big><b>Bitte JavaScript einschalten!</b></big></font><br> </noscript> <div id="ergebnisanzeige">Bitte die ersten Buchstaben eingeben (entweder a oder x) und das gesuchte Wort mit der Maus anklicken</div> <br> <form name="formular" action="#"> <input type="text" id="eingabefeld" onKeyUp="meinAjaxAufruf( this.value )" style="width: 162px;" /><br> <div id="auswahlbox" style="width: 160px; border: 1px solid #223377;"></div> </form> </body> </html>
Erläuterungen:
Ergänzen Sie folgendermaßen das Ajax-Beispiel für Autovervollständigung. Erzeugen Sie im bereits angelegten Tomcat-'webapps/ROOT/ajax'-Unterverzeichnis folgende JSP-Datei 'autovervollstaendigung.jsp':
<%! static final String[] meinTextArray = { "aabbcc", "abc 1", "abc1", "abc2", "ajax1", "ajax2", "xyzax", "xyzäx", "xyzbx", "xyzzx" }; boolean sorted = false; %> <% response.setHeader("Cache-Control", "no-cache"); String eingabe = request.getParameter( "eingabe" ); if( null != eingabe && 0 < eingabe.trim().length() ) { if( !sorted ) { java.util.Arrays.sort( meinTextArray ); sorted = true; } StringBuffer auswahl = new StringBuffer(); boolean resultFound = false; for( int i=0; i<meinTextArray.length; i++ ) { if( meinTextArray[i].startsWith( eingabe ) ) { auswahl.append( meinTextArray[i] ).append( ";" ); resultFound = true; } else { if( resultFound ) break; } } if( 0 < auswahl.length() ) { auswahl.setLength( auswahl.length() - 1 ); } out.println( auswahl.toString() ); } %>
'autovervollstaendigung.jsp' returniert zu den übergebenen Zeichen passende durch ';' getrennte Textstrings. Überprüfen Sie dies (bei laufendem Tomcat) über den Aufruf von http://localhost:8080/ajax/autovervollstaendigung.jsp?eingabe=a und http://localhost:8080/ajax/autovervollstaendigung.jsp?eingabe=x.