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 1Literatur
[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 2AJAX
• 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 3Geschichte 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 4Beispiel 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 5Kommunikation 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 6Anfrage an den Server senden I
function sendRequest(url, params, method, async) {
if(arguments.lengthAnfrage 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 8Anfrage 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 9Antwort 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 10Antwort 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 11Antwort 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 12write2console()
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 13Beispiel2 – 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 15Das 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 16HTML-Datei auf dem Server I
Das ist das PHP-Programm, das die Ajax-Daten sendet.
Das Ergebnis:
AVS – SS 2015 - Teil 9/Ajax 17HTML-Datei auf dem Server II – Mit Parameter
Der Parameter
Das Ergebnis:
AVS – SS 2015 - Teil 9/Ajax 18HTML-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 19HTML-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 20Beispiel 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 22XMLHttpRequest-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 23XMLHttpRequest-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 24Arbeiten 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 25Arbeiten 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 26JSON-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 27Grammatik 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 28Beispiel 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 29Beispiel 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 30Beispiel 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 31Wie 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 32W3C 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 33DOM-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 34Ereignisse 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 35Ereignisse 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 36Ereignisse 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 37Ereignisse 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 38Beispiel 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 39Beispiel 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 40Nach dieser Anstrengung etwas Entspannung... AVS – SS 2015 - Teil 9/Ajax 41
Sie können auch lesen