Architektur Verteilter Systeme Teil 9: JSON und etwas AJAX (Vertiefende Wiederholung)
←
→
Transkription von Seiteninhalten
Wenn Ihr Browser die Seite nicht korrekt rendert, bitte, lesen Sie den Inhalt der Seite unten
Architektur Verteilter Systeme Teil 9: JSON und etwas AJAX (Vertiefende Wiederholung) AVS – SS 2015 - Teil 9/Ajax 03.06.15 1
Literatur [17-01] http://www.json.org http://oss.metaparadigm.com/jsonrpc [17-03] Steyer, Ralph: Das JavaScript Codebook. 2. Auflage, Addison-Wesley, 2005 [17-05] Flanagan, David: JavaScript kurz&gut. O'Reilly, 4. Auflage, 2012 [17-06] Crane, Dave; Pascarello, Eric; James, Darren: Ajax in action. Addison- Wesley, 2006 [17-07] Bergmann, Olaf; Bormann, Carsten: AJAX. SPC TEIA Lehrbuch Verlag, 2005 [17-08] Perry, Bruce: AJAX Hacks. O'Reilly, 2006 [17-09] Steyer, Ralph: AJAX mit PHP. Addison-Wesley, 2006 [17-14] Lauriat, Shawn: Advanced Ajax. Prentice Hall, 2008 [17-15] Wenz, Christian: Ajax. Entwickler.press, 2006 AVS – SS 2015 - Teil 9/Ajax 2
AJAX • AJAX = Asynchronous JavaScript and XML • Ajax ist ein Verfahren Teile von angezeigten Web-Seiten direkt zu ersetzen anstatt die ganze Seite neu zu laden. • Dazu werden mit JavaScript im Hintergrund XML-Daten vom Server geholt und im Browser dargestellt. • Diese XML-Daten werden in JavaScript-Objekte konvertiert, die in das DOM des Dokuments integriert und somit angezeigt werden. • Ajax funktioniert nur bei Browsern, die das XMLHttpRequest-Objekt realisiert haben, ab Firefox 1.0, Explorer 5, Opera 8, Mozilla 1.4, Netscape 7.1, Safari 1.2, Konqueror 3.2 und iCab 3.0. Wenn statt XML-Daten JSON-Daten verwendet werden, lassen sich dieselbe Effekte ohne den Overhead von XML realisieren. Dies wird im folgenden getan. AVS – SS 2015 - Teil 9/Ajax 3
Geschichte von JSON • JSON = JavaScript Object Notation • Entwickelt von Douglas Crockford, 2002 • Definiert in RFC 4627 (Juli 2006) • JSON ist ein Serialisierungsformat von JavaScript-Objekten basierend auf ASCII. • JSON ist eine Untermenge von JavaScript und kann daher direkt mit der eval()-Funktion interpretiert bzw. bei der Objekt- Erzeugung benutzt werden. Siehe: http://en.wikipedia.org/wiki/json http://tools.ietf.org/html/rfc4627 AVS – SS 2015 - Teil 9/Ajax 4
Beispiel von JSON { "firstName": "John", "lastName": "Smith", "age": 25, "address": { "streetAddress": "21 2nd Street", "city": "New York", "state": "NY", "postalCode": "10021" }, "phoneNumber": [ { "type": "home", "number": "212 555-1234" }, { "type": "fax", "number": "646 555-4567" } ] } Das Beispiel stammt aus: http://en.wikipedia.org/wiki/.json AVS – SS 2015 - Teil 9/Ajax 5
Kommunikation mit Server Ajax.css ajax() Ajax.html Ajax.js sendRequest() Event getHTTPRequest() processChange() XMLHttpRequest() processReady() write2console() Nun kommt eine einfache Version für die Ajax-Kommunikation. addNode() AVS – SS 2015 - Teil 9/Ajax 6
Anfrage an den Server senden I function sendRequest(url, params, method, async) { if(arguments.length
Anfrage an den Server senden II function getHTTPRequest() { var req= null; if(typeof XMLHttpRequest != "undefined") { req= new XMLHttpRequest();// Mozilla und Co. } else { if(typeof ActiveXObject != "undefined") { req= new ActiveXObject("Microsoft.XMLHTTP"); if(!req) { req= new ActiveXObject("Msxml2.XMLHTTP"); } } } return req; } Tja, und hier holt uns die Geschichte der Inkompatibilitäten ein... - weiter unten kommt noch mehr. AVS – SS 2015 - Teil 9/Ajax 8
Anfrage an den Server senden III - Verbesserung ... Statt request.send(params); } } ... Besser if(params!=null) { request.send(params); } else { request.send(); } } } sendRequest() kann nun auch Parameter an den Server senden. Diese müssen aber in der urlencoded-Form kodiert sein, z.B. sendRequest(URL,"msg="+escape("Es ist"),"POST"); AVS – SS 2015 - Teil 9/Ajax 9
Antwort vom Server holen I var request= null; // globale Variable (XMLHttpRequest) function sendRequest(url, params, method, async) { ... if(request!=null) { request.onreadystatechange= processChange; // Call Back request.open(method, url, async); ... } Um etwas vom Server empfangen zu können, muss eine Routine als ein "Call Back" definiert werden. AVS – SS 2015 - Teil 9/Ajax 10
Antwort vom Server holen II function processChange() { var STATE_UNINITIALIZED= 0; //"Konstanten" definieren var STATE_LOADING = 1; var STATE_LOADED = 2; var STATE_INTERACTIVE = 3; var STATE_COMPLETE = 4; if(request.readyState == STATE_COMPLETE) { // Status-Code abfragen if(request.status==200) { // hier findet die Verarbeitung des Textes statt processReady(request.responseText); } else { // Behandlung des Fehlers } } } Das ist die Routine, die dann asynchron bei jeder Zustandsänderung der Verbindung zum Server aufgerufen wird. AVS – SS 2015 - Teil 9/Ajax 11
Antwort vom Server holen III function processReady(text) { write2console(text); } Das ist die Verarbeitungsroutine, die Daten vom Server als Text mit Hilfe der Routine write2console() ausgibt. AVS – SS 2015 - Teil 9/Ajax 12
write2console() var console= null; function addNode(elem, text) { var newText= document.createTextNode(text); elem.appendChild(newText); } function write2console(text) { if(console==null) { console= document.getElementById("Comment"); } addNode(console,text); } Zur Ausgabe in JavaScript wird ein Knoten im DOM erzeugt und hinten angehängt. Dies wird durch die Routine write2console() verdeckt. AVS – SS 2015 - Teil 9/Ajax 13
Beispiel2 – HTML Teil 1
Bemerkungen • Das vorherigen Beispiel soll nur die prinzipielle Vorgehensweise zeigen; für reale Projekte ist diese Vorgehensweise nur bedingt geeignet: Z.B. ist die Verwendung und gemeinsame Benutzung einer globalen Variablen - hier request - nicht gut, besonders dann, wenn mit mehreren parallelen Requests gearbeitet werden soll. Dann sollte mit Objekten und lokalen Variablen gearbeitet werden. • Wenn beim open() der dritte Parameter false ist, wird "synchron" gesendet, d.h. es wird beim send() auf die Antwort gewartet (also kein Ajax, sondern eher ein Sjax). Bei true wird weiter gemacht, so dass die Anforderung parallel bearbeitet wird. AVS – SS 2015 - Teil 9/Ajax 15
Das Hauptprogramm bzw. der Rest var URL= "http://localhost/Ajax-05-Hello/getDate.php"; var request= null; // globale Variable (XMLHttpRequest) function ajax() { sendRequest(URL,null,"POST"); } AVS – SS 2015 - Teil 9/Ajax 16
HTML-Datei auf dem Server I Das ist das PHP-Programm, das die Ajax-Daten sendet. Das Ergebnis: AVS – SS 2015 - Teil 9/Ajax 17
HTML-Datei auf dem Server II – Mit Parameter Der Parameter Das Ergebnis: AVS – SS 2015 - Teil 9/Ajax 18
HTML-Datei auf dem Server III – Kennzeichnung request= getHTTPRequest(); // Objekt generieren if(request!=null) { request.onreadystatechange= processChange;// Call Back request.open(method, url, async); request.setRequestHeader("Content-Type",………); request.setRequestHeader("x_requested_with","1"); if(params != null) { request.send(params); } else { request.send(); } } Durch einen neuen Header-Eintrag wird der Ajax-Request gekennzeichnet, so dass der Server erkennen kann, ob die URL von Ajax her oder über einen Browser direkt angesteuert wurde. AVS – SS 2015 - Teil 9/Ajax 19
HTML-Datei auf dem Server IV – Kennzeichnung if(isset($_POST['msg'])) { $mesg= $_POST['msg']; } else { $mesg= 'Now is'; } $requestHeader= apache_request_headers(); if(isset($requestHeader['x_requested_with'])) { echo "\n$mesg ".strftime("%d.%m.%Y %H:%M:%S")."\n\n"; } else { echo ''; echo ''; echo ''; echo 'Ajax Hello'; echo "\n$mesg ".strftime("%d.%m.%Y %H:%M:%S").""; } So sieht die dazu gehörige Seite auf dem Server aus. Die Abfrage apache_request_headers() läuft nur auf dem Apache. AVS – SS 2015 - Teil 9/Ajax 20
Beispiel 3 – Das Ergebnis Fertig! Zugriff direkt auf die Seite AVS – SS 2015 - Teil 9/Ajax 21
XMLHttpRequest-Objekt I Attribut Erläuterung onreadystatechange Adresse der Call Back Routine, die bei allen Änderungen von readyState aufgerufen wird readyState Zustände 0 bis 4 (siehe Code oben) STATE_UNINITIALIZED= 0 STATE_LOADING= 1 STATE_LOADED= 2 STATE_INTERACTIVE= 3 STATE_COMPLETE= 4 responseText Einfacher Text der Antwort responseXML Antwort im XML-Format status HTTP-Status-Code der Antwort statusText HTTP-Status-Code als Text AVS – SS 2015 - Teil 9/Ajax 22
XMLHttpRequest-Objekt II - readyState Zustand Erläuterung 0 Nicht initialisiert, also vor open()-Aufruf 1 Initialisiert, aber kein Absenden, also vor send()-Aufruf 2 send() wurde ausgeführt 3 Empfangen der Antwort, warten auf das Ende des Empfangens; es kann schon auf responseText zugegriffen werden 4 Alles fertig; responseText enthält den vollständigen Text Dasselbe gilt für responseXML. Ein Abbrechen mittels abort() ist nur in den Zuständen 2 und 3 sinnvoll. AVS – SS 2015 - Teil 9/Ajax 23
XMLHttpRequest-Objekt III Methode Erläuterung abort() Abbruch des Requests getAllResponseHeaders() Gibt den gesamten Header in einem String zurück getResponseHeader(string) Gibt den Wert eines Header-Teiles zurück open(string method, string url, string Bereitet Request an Adresse url vor; asyn gibt asyn) als String an, ob asynchron ("true") oder nicht ("false") send(string) Absenden des Requests, wobei der String Parameter angibt, die nach einem ? hinter der URL angefügt werden setHeader(string header, string val) Setzen einer Header-Zeile • open() hat noch zwei weitere optionale Parameter: – 4. Parameter: Benutzernamen – 5. Parameter: Passwort AVS – SS 2015 - Teil 9/Ajax 24
Arbeiten mit JSON I • Wenn die empfangenen Zeichenkette in JSON-Format vorliegt, kann daraus unmittelbar ein JavaScript-Objekt gemacht werden. • Dann können die einzelnen Attribute aus diesem Objekt ausgelesen und in das DOM der Seite integriert werden. • Einzig was sich ändert, ist die Call-Back-Routine bzw. die Verarbeitungsroutine processReady(): function processReady(text) { var obj= eval("("+text+")"); // Arbeiten mit obj, z.B. obj.Vorname... } AVS – SS 2015 - Teil 9/Ajax 25
Arbeiten mit JSON II var obj= eval("("+resp+")"); • Diese Lösung erzeugt per Interpretation des empfangenen Textes, z.B. ein JSON-String, einen Wert oder ein Objekt. Z.B. „{ x:10, y:20, sum:30 }“ • Die beiden Klammern müssen gesetzt werden. • Die Abfrage des HTTP-Statuscodes dient dazu, Fehler des Servers abzufangen bzw. zu behandeln (siehe Teil über HTTP). • Die Statuscodes zwischen 100 und 199 werden für Zwischennachrichten benutzt; sie zeigen keine Beendigung an. • Zum Liefern von Informationen braucht der Server nur die Daten im JSON-Format zu liefern. • Bei "echten" Ajax-Anwendungen ist es eine XML-Information. AVS – SS 2015 - Teil 9/Ajax 26
JSON-Format • Ein Objekt wird innerhalb geschweifter Klammern {} definiert. • Es können Objekte geschachtelt werden, aber nie auf der obersten Ebene mehr als ein Objekt. • Arrays werden durch eckige Klammern [] definiert. • Attribute werden jeweils durch ein Paar Name: Wert definiert. AVS – SS 2015 - Teil 9/Ajax 27
Grammatik des JSON-Formates Object = "{" [members] "}" members = string : value { , string : value }* array = "[" [elements] "]" elements= value {, value}* value = string | number | object | array | "true" | "false"| "null" string = " [chars] " chars = char { char }* char = any-Unicode-except-"-or-\-or-control | \" | \\ | \/ | \b | \f | \n | \r | \t | \u four-hex- digits number = int [ frac | exp | frac exp ] int = [ - ] { digit | digit1-9 digits } frac = . digits exp = e digits digits = digit+ e = "e" | "e+" | "e-" | "E" | "E+" | "E-" AVS – SS 2015 - Teil 9/Ajax 28
Beispiel I { "window": { "tracing": "off", "window": { "title" : "Faenster", "name" : "Window", "width" : 600, "height": 800 }, "image": { "src" : "Images/BlueSky.jpg", "name" : "background", "hOffset" : 0, "vOffset" : 0, "alignment": "center" }, AVS – SS 2015 - Teil 9/Ajax 29
Beispiel II "text": { "data" : "Hallo World!", "size" : 48, "style" : "bold", "name" : "Teaser", "hOffset" : 10, "vOffset" : 30, "alignment": "center" } } } Beispiel für geschachtelte Objekte AVS – SS 2015 - Teil 9/Ajax 30
Beispiel aus RFC 4627 [ { "precision": "zip", "Latitude": 37.7668, "Longitude": -122.3959, "Address": "", "City": "SAN FRANCISCO", "Zip": "94107", "Country": "US" },{ "precision": "zip", "Latitude": 37.371991, "Longitude": -122.026020, "Address": "", "City": "SUNNYVALE", "Zip": "94085", "Country": "US" Beispiel für ein Array von }] Objekten AVS – SS 2015 - Teil 9/Ajax 31
Wie setzt sich alles zusammen? • Nach Klicken auf Knöpfe werden JavaScript-Routinen gestartet, die dann die Requests absetzen. • Über onXYZ-Ereignisse, z.B. Änderung des Fokus, MouseOver etc., werden JavaScript-Routinen gestartet. • Das einzige, was nicht geht, ist das Aktiv-Werden des Servers ohne Interaktion durch den Client. AVS – SS 2015 - Teil 9/Ajax 32
W3C DOM II – Suchen anhand von Merkmalen document.getElementById("String") Zugriff auf ein Element/Tag mit Attribut id=String. document.getElementsByTagName("String") Zugriff auf Elemente, wobei diese in einem Array geliefert werden, z.B. Zugriff auf den 3. Absatz: document.getElementsByTagName("p")[2] document.getElementsByName("String") Zugriff auf Elemente mit Attribut name=String, wobei diese in einem Array geliefert werden AVS – SS 2015 - Teil 9/Ajax 33
DOM-Operationen V - innerHTML Es kann auch direkter HTML-Code eingefügt werden: ... elem.innerHTML +="..."; ... Das Überschreiben erfolgt durch einfache Zuweisung, d.h. durch Ersetzen der Knoten. AVS – SS 2015 - Teil 9/Ajax 34
Ereignisse im -Tag • Event = Ereignis = Etwas, was der Browser festgestellt hat und das durch JavaScript behandelt werden kann • Events und ihre Behandlung stellen die Basis für Dynamik der dargestellten Seite dar. function sagHallo() { ... } function sagTschuess() { ... } ... Event-Handler Aktivierung onLoad Wenn das Dokument geladen ist onUnload Wenn das Dokument geschlossen oder verlassen wird AVS – SS 2015 - Teil 9/Ajax 35
Ereignisse bei Graphik, Links, Anker I Das Anwendungsgebiet liegt hierbei in der dynamischen Änderung des Dokuments, z. B. in Abhängigkeit von Eingaben. ...und natürlich in netten Spielereien. Event-Handler Aktivierung onClick Nein Ja bei Klick auf den Link onMouseout Ja Ja wenn die Maus das Objekt verlässt onMouseover Ja Ja wenn die Maus über dem Objekt ist AVS – SS 2015 - Teil 9/Ajax 36
Ereignisse bei Graphik, Links, Anker II var Pictures= new Array; Pictures[0]= new Image; Pictures[0].src= URL1; Pictures[1]= new Image; Pictures[1].src= URL2; function Pict(nr) { document.images[0].src=Pictures[nr].src; } • Wenn die Maus sich oberhalb des einen Links befindet, wird die Graphik ausgetauscht - wird dann die Maus wegbewegt, wird die alte Graphik wieder angezeigt. • Dies ist ein Rollover-Effekt mit zwei Graphiken – nette Spielerei. AVS – SS 2015 - Teil 9/Ajax 37
Ereignisse in Formularen Event input type/Form Aktivierung onBlur select text textarea Wenn Benutzer das Feld verlässt, d.h. wenn das Feld den Fokus verliert onKeyUp Wenn ein Zeichen eingegeben wurde onChange select text textarea Wenn das Feld den Fokus verliert und eine Änderung gemacht wurde onClick button checkbox radio reset Wenn Benutzer das Feld anklickt submit onFocus select text textarea Wenn Benutzer das Feld aktiviert, d.h. wenn das Feld den Fokus erhält onReset form Bei Drücken des RESET-Knopfes onSelect text textarea Wenn Benutzer eine Textstelle markiert onSubmit form Bei Drücken des SUBMIT-Knopfes AVS – SS 2015 - Teil 9/Ajax 38
Beispiel I – Kleiner Umrechner function Rechner() { var Money= document.EURO.DM.value; var Total= Math.round((Money/1.95583)*100)/100; document.EURO.EUR.value= Total; } ... DM EUR • Der triviale EUR-Umrechner basiert auf der Klickbehandlung im 2. input-Tag. • "document.forms[0]" ist durch "document.EURO" ersetzt. AVS – SS 2015 - Teil 9/Ajax 39
Beispiel II: Besuchsdauer start= new Date(); startzeit= start.getTime(); function Stoppuhr() { jetzt= new Date(); zeit= (jetzt.getTime()-startzeit)/1000; document.Hier.Dauer.value= Math.round(zeit); setTimeout('Stoppuhr()', 1000); } ... Du bist schon Sekunden hier. • Alle 1000ms wird die Funktion Stoppuhr() aufgerufen, die die Zeitdifferenz zum ersten Aufruf berechnet und ausgibt. • Direkt nach dem Laden wird Stoppuhr() sofort aufgerufen. AVS – SS 2015 - Teil 9/Ajax 40
Nach dieser Anstrengung etwas Entspannung... AVS – SS 2015 - Teil 9/Ajax 41
Sie können auch lesen