Architektur Verteilter Systeme Teil 9: JSON und etwas AJAX (Vertiefende Wiederholung)

Die Seite wird erstellt Lenny-Stefan Adam
 
WEITER LESEN
Architektur Verteilter Systeme Teil 9: JSON und etwas AJAX (Vertiefende Wiederholung)
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