23
2 Webtechnologien - WS 2018/19 - Teil 14/Ajax Literatur [14-01] http://www.json.org http://oss.metaparadigm.com/jsonrpc [14-02] https://www.w3schools.com/js/js_json_intro.asp [14-03] Steyer, Ralph: Das JavaScript Codebook. 2. Auflage, Addison-Wesley, 2005 [14-04] Flanagan, David: JavaScript – Das umfassende Referenzwerk. O'Reilly, 6. Auflage, 2012 (1.200 Seiten) [14-05] Flanagan, David: JavaScript kurz&gut. O'Reilly, 4. Auflage, 2012 [14-06] Crane, Dave; Pascarello, Eric; James, Darren: Ajax in action. Addison- Wesley, 2006 [14-07] Bergmann, Olaf; Bormann, Carsten: AJAX. SPC TEIA Lehrbuch Verlag, 2005

Webtechnologien - WS 2018/19 - Teil 14/Ajaxwi.f4.htw-berlin.de/users/messer/LV/WI-WT-WS18/Folien/WT-14/14-WT...Webtechnologien - WS 2018/19 - Teil 14/Ajax 9 JSON-Format • Ein Objekt

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

2Webtechnologien - WS 2018/19 - Teil 14/Ajax

Literatur

[14-01] http://www.json.orghttp://oss.metaparadigm.com/jsonrpc

[14-02] https://www.w3schools.com/js/js_json_intro.asp

[14-03] Steyer, Ralph: Das JavaScript Codebook. 2. Auflage, Addison-Wesley, 2005

[14-04] Flanagan, David: JavaScript – Das umfassende Referenzwerk. O'Reilly, 6. Auflage, 2012 (1.200 Seiten)

[14-05] Flanagan, David: JavaScript kurz&gut. O'Reilly, 4. Auflage, 2012

[14-06] Crane, Dave; Pascarello, Eric; James, Darren: Ajax in action. Addison-Wesley, 2006

[14-07] Bergmann, Olaf; Bormann, Carsten: AJAX. SPC TEIA Lehrbuch Verlag, 2005

3Webtechnologien - WS 2018/19 - Teil 14/Ajax

Literatur zu Ajax

[14-08] Perry, Bruce: AJAX Hacks. O'Reilly, 2006

[14-09] Steyer, Ralph: AJAX mit PHP. Addison-Wesley, 2006

[14-10] Koch, Daniel: Schnell plakatiert. CT 20/2005, S.196-199

[14-11] Wang, Dapeng: Nicht nur holländische Fußballkunst. Javamagazin, 11, 2005, S. 92-97

[14-12] Braun, Herbert: Ajax zu Fuß. CT 5/2006, S.152-159

[14-13] Braun, Herbert: Instant-Ajax. CT 5/2006, S.160-162

[14-14] Lauriat, Shawn: Advanced Ajax. Prentice Hall, 2008

[14-15] Wenz, Christian: Ajax. Entwickler.press, 2006

[14-16] http://www.json.org/

[14-17] http://www.webmasterpro.de/coding/article/json-als-xml-alternative.html

4Webtechnologien - WS 2018/19 - Teil 14/Ajax

Übersicht

• Ajax

• JSON

• Fertige Routine

5Webtechnologien - WS 2018/19 - Teil 14/Ajax

AJAX I

• AJAX = Asynchronous JavaScript and XML

• Ajax ist ein Verfahren Teile von angezeigten Web-Seiten direkt zu ersetzen anstatt die ganze Seite neu zu laden.

• Diese Idee ist recht alt und wurde lange vor dem "Ajax-Hype" realisiert, u.a. von Google und Microsoft.

• Der Begriff AJAX wurde von Jesse James Garret in seinem Artikel "Ajax: A New Approach to Web Applications" 2005 bekannt gemacht.

http://www.adaptivepath.com/publications/essays/archives/000385.php

6Webtechnologien - WS 2018/19 - Teil 14/Ajax

AJAX II

• 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 bei allen modernen Browsern, die das XMLHttpRequest-Objekt realisiert haben.

Wenn statt XML-Daten JSON-Daten verwendet werden, lassen sich dieselbe Effekte ohne den Overhead von XML realisieren.Dies wird im folgenden getan.

7Webtechnologien - WS 2018/19 - Teil 14/Ajax

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.

• Definition: http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf

Siehe: http://en.wikipedia.org/wiki/jsonhttp://tools.ietf.org/html/rfc4627

8Webtechnologien - WS 2018/19 - Teil 14/Ajax

Beispiel von JSON

{ "Herausgeber": "Humpty",

"Nummer": "1234-5678-9015-3456",

"Deckung": 2e+6,

"Währung": "EUR",

"Inhaber":

{ "Name": "Mustermann",

"Vorname": "Max",

"männlich": true,

"Hobbys": [ "Reiten", "Golf", "Lesen" ],

"Alter": 42,

"Kinder": [],

"Partner": null

}

}

Quelle: https://de.wikipedia.org/wiki/JavaScript_Object_Notation

9Webtechnologien - WS 2018/19 - Teil 14/Ajax

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.

10Webtechnologien - WS 2018/19 - Teil 14/Ajax

Prototypen I

Konstruktor.prototype.Attribut= Ausdruck;

Konstruktor.prototype.Methode= Funktion;

• Der Konstruktor ist der Name der "Klasse".

• Methode ist der Name einer Methode, während Funktion eine Funktionsreferenz ist.

• Zu jedem Konstruktor gibt es ein internes Objekt (prototype), das bei einem new() mit dem generierten Objekt zusammen erzeugt wird und mit ihm verbunden ist.

• Alles, was dem Objekt zugewiesen wird, ist lokal zu dem Objekt.

• Alles, was dem Prototyp zugewiesen wird, ist global zu allen davon generierten Objekten.

• Der Prototyp ist so etwas wie ein Bereich für statische Variablen/Methoden.

• Dies gilt auch NACH der Erzeugung eines Objektes.

11Webtechnologien - WS 2018/19 - Teil 14/Ajax

Prototypen II

Glob1Glob2Glob3…GlobN

Attr1Attr2…AttrN

Attr1Attr2

Attr1Attr2…AttrN

Attr1

Objekt1 Objekt2 Objekt3 Objekt4

Prototype"Globale"Attribute

"Lokale"Attribute

Wie bei derSchachtelungvon Blöcken

Statt Attribute könnenauch Funktionsreferenzenbenutzt werden.

12Webtechnologien - WS 2018/19 - Teil 14/Ajax

Prototypen III

• Es besteht damit eine Verbindung wie ein Zeiger zwischen dem Prototyp-Objekt und dem eigentlichen Objekt derart, – dass eine Erzeugung eines Attributs beim Objekt ein Attribut gleichen

Namens im Prototyp-Objekt überdeckt.

– dass eine Erzeugung eines Attributs beim Prototyp für alle bisherigen und zukünftigen Objekte ein neues Attribut definiert, es sei denn dieser Attributname ist in den jeweiligen Objekten schon definiert - dann überdeckt deren Definition die aus dem Prototyp.

• Wenn im Prototyp wiederum ein anderes mit new() erzeugtes Objekt eingefügt wird, entsteht ein Verweis auf dessen Prototyp, so dass dessen Eigenschaften "vererbt" werden, aber nur "einstufig".

Alle Objekte mit demselben Konstruktor haben auch denselben Prototyp.Verschiedene Konstruktoren haben auch verschiedene Prototypen.

13Webtechnologien - WS 2018/19 - Teil 14/Ajax

Prototypen IV - Anwendungen

• Die Prototypen dienen zur Definition von Methoden, die nur einmal zugewiesen werden brauchen, anstatt jeweils nach einem new().

• Damit korrespondierend werden im Prototypen auch die allgemeinen Attribute, die in den Methoden als „globale“ Variablen benutzt werden, definiert.

• In Wirklichkeit liegt noch der Prototyp Object.prototype über allen Prototypen, so dass eigentlich drei Ebenen vorhanden sind.

14Webtechnologien - WS 2018/19 - Teil 14/Ajax

Kommunikation mit Server - Überblick

newXHR()

sendRequest()

XMLHttpRequest()

receivedText()

receive()

ajax()

index.php

Display.js

Ajax.js

Nun kommt eine einfache Version fürdie Ajax-Kommunikation.

Event

ErrorHandler()

15Webtechnologien - WS 2018/19 - Teil 14/Ajax

"Hauptprogramm" index.php I

(01) <body>(02) <p>Hier stehen die Dinge der Seite und noch mehr(03) </body>(04) <script type="text/javascript" src="js/Ajax.js"></script>(05) <script type="text/javascript" src="js/Display.js"></script>(06) <script type="text/javascript">(07) var URL= "http://localhost/JS-Ajax/getDate.php";(08) var ajaxs= new Ajax(URL);(09) ajaxs.send({"msg": "Heute ist "});(10) var obj= ajaxs.receive({"date": 0});(11) writeln(obj.date);(12) ajaxs.disconnect(); (13) </script>

16Webtechnologien - WS 2018/19 - Teil 14/Ajax

"Hauptprogramm" index.php II - Bemerkungen

• In (08) wird das Objekt, das die Kommunikation realisiert, erzeugt.

• In (09) wird mit Hilfe der POST-Methode eine Nachricht bestehend aus einem Parameter msg und dem Wert "Heute ist " an den Server mit der URL aus (07).

• In der nächsten Zeile (10) wird der als JSON empfangene Wert geholt, gefiltert und der Variablen obj als Objekt zugewiesen.

• Mit {"date": 0} wird ein Filter definiert, das dazu dient, dass nur die Elemente aus dem empfangenen JSON-Paket benutzt werden, die im Filter definiert sind, hier nur "date".

• In (11) wird die Komponenten date ausgelesen und ausgegeben.

• In (12) wird das Ajax-Objekt nach dem Benutzung wieder freigegeben (ist nicht nötig, da dies am Ende immer erfolgt).

17Webtechnologien - WS 2018/19 - Teil 14/Ajax

GetDate.php – die Serverseite

(01) if (isset($_POST['msg'])) {(02) $mesg= filter_input(INPUT_POST,'msg');(03) } else {(04) $mesg = 'Now is';(05) }(06) (07) $message= "$mesg ".strftime('%d.%m.%Y %H:%M:%S');(08) echo json_encode(array('date' => $message));(09)

• Zeilen (01-05) sind die normale Bearbeitung von POST-Parametern in PHP samt Defaultwert.

• In (07) wird das aktuelle Datum mit Zeit zusammen mit dem Parameter gesetzt, um in (08) als Teil eines Hash benutzt zu werden: array('date' => $message). Dieser Hash ist die Grundlage für das JSON-Objekt, das aus dem Hash erzeugt und mit echo "ausgegeben" wird.

• Das JSON-Objekt wird als Antwort an den Browser geschickt und dort mit receive() - siehe oben – empfangen bzw. gefiltert.

18Webtechnologien - WS 2018/19 - Teil 14/Ajax

Die Kommunikation I

Das Ergebnis im Browser

Analyse der Datenkommunikation im Webentwickler-Modus des Firefox

19Webtechnologien - WS 2018/19 - Teil 14/Ajax

Die Kommunikation II

Die Anfrage allgemein

Der Hinweg

Der Rückweg

20Webtechnologien - WS 2018/19 - Teil 14/Ajax

Ajax.js I

(01) function Ajax(url,myHandler= null) {(02) var here= this; (03) this.url= url;(04) this.myHandler= myHandler;(05) this.method= "POST"; (06) this.responseText= null;(07) this.request= Ajax.prototype.newXHR();(08) this.request.onreadystatechange= function(){(09) here.receivedText(); (10) if(myHandler!==null) {(11) here.myHandler(here.request);(12) }(13) };(14) };

Das ist der Konstruktor Ajax (der auch den Prototyp realisiert).

21Webtechnologien - WS 2018/19 - Teil 14/Ajax

Ajax.js II - Bemerkungen

• Der 1. Parameter ist die URL des Servers und der zweite optionale Parameter die Funktionsreferenz auf einen Handler, der die empfangenen Daten verarbeiten kann – später dazu mehr.

• In (02) wird eine lokale Variable mit der Adresse des eigenen Objekts gesetzt, was später wichtig wird.

• In (04-07) werden in Objekt-Variablen ein paar Werte abgelegt.

• Der Aufruf von newXHR() erzeugt ein XMLHttpRequest-Objekt.

• In (08) wird eine anonyme Funktion als Handler eines Ereignisses registriert (Listener/Observer-Muster); diese Routine ist eine Callback-Routine, die beim Empfang der Daten parallel zur Ausführung anderer Routinen aufgerufen wird.

• Die Registrierung erfolgt in der Variablen onreadystatechange. Immer wenn sich an der Kommunikation etwas ändert, wird die hier registrierte Routine aufgerufen.

22Webtechnologien - WS 2018/19 - Teil 14/Ajax

Ajax.js III - Bemerkungen

• Die anonyme Funktion ist ein Closure mit dem Zugriff auf die globalen Variablen here und myHandler.

• Von denen wird bei der Definition eine Kopie gemacht, so dass deren Wert mit dem Closure fest verbunden ist. Daher musste auch this in die lokale Variable here kopiert werden (02). this kann nicht als Wert eines Closures fungieren.

• In (10) wird gefragt, ob eine eigene Routine zur Behandlung der empfangenen Daten definiert ist; falls ja, wird diese in (11) aufgerufen (und dabei die Verweise auf das eigene Objekt mit here realisiert).

• Dies ist deshalb erforderlich, weil diese Funktion unabhängig vom Rest aufgerufen wird.

(08) this.request.onreadystatechange= function(){(09) here.receivedText(); (10) if(myHandler!==null) {(11) here.myHandler(here.request);(12) }(13) };

23Webtechnologien - WS 2018/19 - Teil 14/Ajax

Ajax.js IV - Bemerkungen

• In (09) erfolgt der Aufruf here.receivedText(); diese Routine ist lokal zum Ajax-Objekt (here hat ja den Wert von this).

• Diese Routine wird später erklärt. Sie führt den Empfang aus.

• Analoges gilt für Zeile (11); hier wird die per Parameter übergebenen (anonyme) Funktion im Kontext des Objektes ausgeführt.

24Webtechnologien - WS 2018/19 - Teil 14/Ajax

Ajax.js V - newXHR()

Tja, und hier holt uns die Geschichte der Inkompatibilitätenein... - weiter unten kommt noch mehr.

(01) Ajax.prototype.newXHR= function() {(02) var req= null;(03) if (typeof XMLHttpRequest !== "undefined") {(04) req= new XMLHttpRequest(); // Mozilla etc(05) } else {(06) if (typeof ActiveXObject !== "undefined") {(07) req= new ActiveXObject("Microsoft.XMLHTTP");(08) if (!req) {(09) req= new ActiveXObject("Msxml2.XMLHTTP");(10) }(11) } else {(12) Ajax.prototype.ErrorHandler(13) ("cant create XMLHttpRequest-Object");(14) }(15) }(16) return req; };

25Webtechnologien - WS 2018/19 - Teil 14/Ajax

Ajax.js VI - newXHR() - Bemerkungen

• newXHR() erzeugt ein neues XMLHttpRequest-Objekt (abgekürzt durch XHR); leider sind nicht alle Browser gleich, so dass hier eine Kaskade von Versuchen ablaufen muss.

• Diese Routine wird in (01) zum Prototypen hinzugefügt und ist daher für alle ajax-Objekte gleichermaßen verfügbar.

• In (03) wird geprüft, ob die Funktion XMLHttpRequest() definiert ist – so wird nach der Existenz gefragt, während eine Abfrage nach null die Existenz voraussetzt.

• In (12) wird eine Fehlermeldung durch den ErrorHandler ausgegeben.

26Webtechnologien - WS 2018/19 - Teil 14/Ajax

Ajax.js VII - ErrorHandler()

• Es wird die Fehlermeldung errMSG ausgegeben, falls writeln() definiert ist (03), ansonsten mit console.log() in (05).

• Optional wird eine Exception in (08) mit der Fehlermeldung geworfen.

(01) Ajax.prototype.ErrorHandler= function(errMsg,doThrow= true) {(02) if(typeof writeln !== "undefined") {(03) writeln(errMsg);(04) } else {(05) console.log(errMsg);(06) }(07) if(doThrow) {(08) throw errMsg;(09) }(10) };

27Webtechnologien - WS 2018/19 - Teil 14/Ajax

Ajax.js VIII - sendRequest()

(01) Ajax.prototype.sendRequest= (02) function(url,params=null,method="POST"){(03) try {(04) this.responseText= null;(05) this.request.open(method,url,false);(06) this.request.setRequestHeader((07) "Content-Type","application/x-www-form-urlencoded");(08) this.request.setRequestHeader("x_requested_with","42");(09) if(typeof params==="object") {(10) this.request.send(this.codeParams(params));(11) } else {(12) this.request.send();(13) }(14) } catch (err) {(15) Ajax.prototype.ErrorHandler(err);(16) }(17)};

28Webtechnologien - WS 2018/19 - Teil 14/Ajax

Ajax.js IX – sendRequest() - Bemerkungen

• Es können Parameter (02) für den HTTP-Request übergeben werden; diese werden in der Form keyword=value& keyword=value… gesendet.

• In (06) wird die Kodierung der Anfrage definiert und in (08) ein spezieller Header, der individuell für die Anwendung ist; er muss mit x_ beginnen, der Rest ist frei.

• In (10) bzw. (12) wird gesendet; die Parameter müssen noch entsprechend (06) umkodiert werden: das wird von der Funktion codeParams() geleistet.

open()

Header

send()

Ablauf des Sendensnach Registrierung derCall-Back-Routine

29Webtechnologien - WS 2018/19 - Teil 14/Ajax

Die Sache mit dem speziellen Header I

Damit der Server einen Ajax-Request von einem HTTP-Request durchden Browser/Surfer unterscheiden kann, wird ein fiktiver, ansonsten niegebrauchter Header bei Ajax eingeführt, der nie durch einen Browsergeneriert wird, hier: x_requested_with

(01) $requestHeader= apache_request_headers();(02) if(isset($requestHeader['x_requested_with'])) {(03) if (isset($_POST['msg'])) {(04) $mesg= filter_input(INPUT_POST,'msg');(05) } else {(06) $mesg= 'Now is';(07) }(08) echo 'Simulation of an error message before JSON';(09) $message= "$mesg ".strftime('%d.%m.%Y %H:%M:%S');(10) echo json_encode(array('date' => $message));(11) echo 'Simulation of an error message after JSON';(12) } else {(13) header("HTTP/1.1 404 Not Found");(14) }

30Webtechnologien - WS 2018/19 - Teil 14/Ajax

Die Sache mit dem speziellen Header II - Bemerkungen

• (03-07) und (09-10) wurden schon erklärt.

• Für den Apache-Webserver werden in (01) alle HTTP-Header-Informationen in ein PHP-Hash kopiert.

• In (02) wird abgefragt, ob der spezielle Header dabei ist. Falls nicht, wird eine 404-Fehler-Antwort in (13) generiert.

• Ansonsten läuft es ab wie oben beschrieben.

• Die Zeilen (08) und (11) sind noch mysteriös. Diese dienen der Simulation einer PHP-Fehlermeldung, einmal vor dem Generieren des JSON-Objekts und einmal danach.

• Da der Browser ein JSON-Objekt erwartet und keinen sonstigen String würde ein „Abstürzen“ des Servers fatal sein. Auch sollten diese Meldungen während der Entwicklung angezeigt werden. Wie das erfolgt, zeigt die receive()-Routine.

31Webtechnologien - WS 2018/19 - Teil 14/Ajax

Ajax.js X – send()

• send() ruft mit Parametern die obigen sendRequest()-Routine auf.

• Dabei wird der Parameter async auf false gesetzt, d.h. es findet eine synchrone Abfrage statt.

(01) Ajax.prototype.send= function(msg= null) {(02) this.sendRequest(this.url, msg, this.method,false);(03) };

Das ist dann das Ergebnis mit simulierten Fehlermeldungen

32Webtechnologien - WS 2018/19 - Teil 14/Ajax

Zeitlicher Ablauf (synchron)

open()

Header

send()

Callback()

Callback()

Callback()

receive()

Immer, wenn sich der Zustand des XHR-Objekts ändert, wird die Callback- Routine aufgerufen(sollte nicht sein, ist aber so)

Die send()-Funktion terminiert erst, wennder letzte Callback()-Aufruf beendet ist. Es gibtdaher eine echte Pause; daher folgende Warnung:

33Webtechnologien - WS 2018/19 - Teil 14/Ajax

Ajax.js X – Callback-Routine()

(01) Ajax.prototype.receivedText= function() {(02) if(this.request.readyState!==4) {(03) return;(04) }(05) if(this.request.status!==200) {(06) if(this.request.status===404) {(07) Ajax.prototype.ErrorHandler((08) "404 Not Found: "+this.url);(09) } else {(10) this.onError(this);(11) }(12) };

Dies ist die globale Callack()-Routine, die in Ajax() über die registrierteaufgerufen wird (dort Zeile(09)).

34Webtechnologien - WS 2018/19 - Teil 14/Ajax

Ajax.js XI – Callback-Routine() - Bemerkungen

• In (02) wird der Status der Kommunikation abgefragt; dieser ist als Nummer in dem Attribut readyState kodiert. 4 bedeutet: alles ist fertig.

• In (05) wird der Code der Serverantwort (HTTP-Protokoll) abgefragt; 200 bedeutet: Alles OK.

• Ist nicht alles OK, wird in (06) abgefragt, ob es sich um die falsche URL bzw. um ein Vergessen des speziellen HTTP-Headers handelt. Dann wird eine kurze Meldung ausgegeben, ansonsten eine lange (10).

35Webtechnologien - WS 2018/19 - Teil 14/Ajax

XMLHttpRequest-Objekt I - 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.

36Webtechnologien - WS 2018/19 - Teil 14/Ajax

XMLHttpRequest-Objekt II

Attribut Erläuterung

onreadystatechange Adresse der Call Back Routine, die bei Änderungen von readyState aufgerufen wird

readyState Zustände 0 bis 4:STATE_UNINITIALIZED= 0STATE_LOADING= 1STATE_LOADED= 2STATE_INTERACTIVE= 3STATE_COMPLETE= 4

responseText Einfacher Text der Antwort

responseXML Antwort im XML-Format

status HTTP-Status-Code der Antwort

statusText HTTP-Status-Code als Text

Ein Abbrechen mittels abort() ist nur in den Zuständen 2 und3 von readyState sinnvoll.

37Webtechnologien - WS 2018/19 - Teil 14/Ajax

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 asyn)

Bereitet Request an Adresse url vor; asyn gibt 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

38Webtechnologien - WS 2018/19 - Teil 14/Ajax

Ajax.js XI – onError-Routine()

(01) Ajax.prototype.onError= function(obj,err= '') {(02) var str = "Ajax communication error "+err+"\n";(03) str += "URL="+obj.url+"\n";(04) if (typeof obj.request !== "undefined") {(05) str += "XHR-state="+obj.request.readyState+"\n";(06) str += "HTTP-status code="+obj.request.status+"\n";(07) str += "Headers=\n***\n"+(08) obj.request.getAllResponseHeaders()+"***";(09) }(10) Ajax.prototype.ErrorHandler(str);(11) };

Diese Routine wird immer dann aufgerufen, wenn Fehler bei derKommunikation aufgetreten sind. Es wird ein langer String generiert, in demviele \n eingebaut sind; diese werden in writeln() zu <br> umgewandelt.writeln() wird in ErrorHandler() aufgerufen.

39Webtechnologien - WS 2018/19 - Teil 14/Ajax

Ajax.js XII – codeParams()

(01) Ajax.prototype.codeParams= function(params) {(02) var str= "";(03) var amper= false;(04) for(var p in params) {(05) if(amper) {(06) str+= "&";(07) }(08) str+= encodeURI(p)+"="+encodeURI(params[p]);(09) amper= true;(10) }(11) return str;(12) };

CodeParams() konvertiert die Parameterliste für den HTTP-Requestin das URL-encoded-Format um (im HTTP-Header angegeben).Die entscheidende Zeile ist (08): dort werden Keyword und Wert umkodiert.

40Webtechnologien - WS 2018/19 - Teil 14/Ajax

Ajax.js XIII – receive() - Das "Hauptprogramm"

• In Zeile (01) wird als Parameter ein Objekt übergeben, das durch die obige codeParams()-Routine in der richtigen Kodierung in das Request-Paket integriert wird.

• In (02) wird die Antwort, die über die Callback-Aufrufe entgegen genommen wurde über das Filter – eine Art Firewall – in die Variable obj als Objekt kopiert.

• Das Filter dient dazu, dass nur die Elemente geliefert werden, die im Filter angegeben und daher auch erwartet werden, alle anderen Elemente einschließlich der PHP-Fehlermeldungen werden ignoriert.

(01) ajaxs.send({"msg": "Heute ist "});(02) var obj= ajaxs.receive({"date": 0});(03) writeln(obj.date);(04) ajaxs.disconnect();

41Webtechnologien - WS 2018/19 - Teil 14/Ajax

Ajax.js XIV – receive()

(01) Ajax.prototype.receive= function(filter= null) {(02) var received= {};(03) var text= this.request.responseText;(04) if(text===null) {(05) Ajax.prototype.ErrorHandler("no text received");(06) }(07) if(filter===null) {(08) received= JSON.parse(text);(09) } else {(10) var obj= JSON.parse(text);(11) for (var elem in filter) {(12) if(obj[elem]===undefined) {(13) Ajax.prototype.ErrorHandler("missed received value:"+elem);(14) } else {(15) received[elem]= obj[elem];(16) }(17) } (18) }(19) return received;(10)};

VerkürzteVersion

Aus Gründen derIT-Sicherheit ist dieseKonstruktion gefährlich.

42Webtechnologien - WS 2018/19 - Teil 14/Ajax

Ajax.js XV – receive() - Bemerkungen

• Vor der Zeile (06) werden PHP-Fehlermeldungen vor und nach dem JSON-Konstrukt, das immer mit { beginnen muss, entfernt. Das gilt auch dann, wenn der Server keine Daten sendet, dann muss dort ein leeres JSON-Konstrukt „{}“ generiert werden.

• Wenn in den PHP-Fehlermeldungen { oder } vorkommen, funktioniert das Herausfiltern der Meldungen nicht.

• Ohne Filter wird in Zeile (08) alles übernommen, was vom Server kommt. Aus Sicherheitsgründen sollte dies unterlassen werden.

• In (10-17) wird gefiltert: es werden nur die Elemente übernommen, die im Filter-Objekt vorhanden sind.

Das blinde Vertrauen, dass alle Daten vom Server korrekt sind, solltenicht bestehen; daher die Filterung der empfangenen Daten.

43Webtechnologien - WS 2018/19 - Teil 14/Ajax

Das Ergebnis

String vordem JSON-Teil

String hinterdem JSON-Teil

Ajax.prototype.disconnect= function() { this.request= null;};

Es fehlt noch die disconnect()-Routine

Inhalt vomJSON-Teil

44Webtechnologien - WS 2018/19 - Teil 14/Ajax

Definition eigener Behandler I

(01) var URL= "http://localhost/JS-Ajax/getDate.php";(02) var ajaxs= new Ajax(URL, function(xhr){(03) if(xhr.readyState===4) {(04) writeln('myStatus=',xhr.readyState);(05) writeln('myText=',xhr.responseText);(06) }(07) });(08) ajaxs.send({"msg": "Heute ist "});(09) var obj= ajaxs.receive({"date": 0});(10) writeln(obj.date);

• Es wird in (02-07) einen anonyme Funktion definiert, die einen Parameter- das XHR-Objekt – erwartet.

• In (03) wird geprüft, ob tatsächlich die Routine zum Ende des Empfangs aufgerufen wurde (sie wird mehrfach aufgerufen, auch beim synchronen Betrieb).

45Webtechnologien - WS 2018/19 - Teil 14/Ajax

Definition eigener Behandler II

• In (04-05) werden hier Komponenten des XHR-Objekts ausgegeben.

Die beidenzusätzlichenAusgaben

46Webtechnologien - WS 2018/19 - Teil 14/Ajax

Nach dieser Anstrengung etwas Entspannung...