CSS, HTML und Javascript mit {stil}

Javascript JSON

JSON Datenaustausch zwischen Client und Server

JSON steht für Javascript Object Notation und ist ein Textformat für den Austausch von Daten zwischen Client und Server – vom eigenen Webserver oder anderen Services wie Twitter.

JSON wurde für Javascript entwickelt, lehnt sich stark an Javascript-Objekte an und wird heute von vielen Programmiersprachen (C++, C, PHP, Phyton, Java, Ruby … ) unterstützt.

JSON ist das beliebteste Austauschformat, denn JSON ist gut lesbar (selbst besser lesbar als XML), ist einfach, schnell und erzeugt nur wenig Overhead.

JSON und Javascript-Objekte

Ein JSON-Objekt ist eine Sammlung von Schlüssel-Wert-Paaren. Aber obwohl JSON-Objekte fast wie einfache Javascript-Objekte aussehen, gibt es doch Unterschiede.

JSON-Schlüssel sind Strings in doppelten Hochkommas. Links steht der Schlüssel, rechts der Wert.

JSON-Objekt
{"farbe" : "Gelb"} 
    |         |
    |         +-- Wert
    +-- Schlüssel
Javascript-Objekt
var colors = { farbe : "Gelb"}

Javascript-Object und JSON-Objekte sehen sich sehr ähnlich: Die Hochkommas um den Schlüssel unterscheiden die Notation.

Sonderzeichen und Leerzeichen für JSON-Schlüssel sind durchaus korrekt, machen aber das Parsen kompliziert. "füll-farbe" oder "Füll Farbe" wären also valide Schlüssel, aber wenn das JSON-Objekt in ein Javascript-Objekt geparst wird, gehören Bindestriche und Leerzeichen nicht zum Repertoire der gültigen Zeichen für einen Javascript-Variablennamen.

JSON-Werte

string
number
object
array
boolean
null
{
   "boolean": true,
   "null": null,
   "number": 123
}

Boolean, numerische Werte und null sitzen nicht in Hochkommas.

Einfache JSON-Daten

"Name" : "Marsalla"

JSON-Objekte enthalten mehrere Name/Wert-Paare. Hier greift die dot-Notation: object.spezies. Dafür gibt es keine Garantie, dass Javascript die Elemente eines Objekts in der Reihenfolge speichert.

"Name" : "Marsalla", "spezies" : "Katze"

JSON-Arrays sitzen wie normale Javascript-Arrays in eckigen Klammern und der Zugriff erfolgt wie bei einem Array über den Index.

var haustiere = [ 
{ "name" : "Marsalla",   "spezies" : "Katze" }
{ "name" : "Theokrates", "spezies" : "Foxterrier" }
{ "name" : "Wallis",     "spezies" : "Friesländer" }
];

haustiere[1].spezies + " " + haustiere[1].name;

Die Array-Notation brauchen wir immer dann, wenn JSON-Keys Sonderzeichen oder Leerzeichen verwenden und keine validen Javascript-Variablennamen sind.

JSON parse()

JSON muss in Javascript übersetzt – geparst – werden. JSON kann mit Javascript eval geparst werden, aber davon lässt man heute die Finger, denn eval gilt als unerwünscht, funktioniert im strict-Mode nicht und ist aus Javascript verbannt. JSON mit jQuery befreit von Abfragen und Prüfungen auf sehr sehr alte Browser.

Die moderne Alternative ist JSON.parse(), das ist sicherer als eval und wird ab IE8 von allen modernen Browsern unterstützt.

{
   "author"   : "Schuiten und Peters",
   "book"     : {
      "title"    : "Bruesel", 
      "published": "1992", 
      "image"    : "https://www.mediaevent.de/javascript/img/bruesel.jpg"
   }
}

Der Zugriff auf die Daten ist denkbar einfach. Zuerst parsen mit JSON.parse() – und schon steht in obj ein Javascript-Objekt mit obj.author oder obj.book.published parat.

var comic = '{"author":"Schuiten und Peters", "book": {"title":"Bruesel", "published":"1992", "image":"https://www.mediaevent.de/javascript/img/bruesel.jpg"}}';
var obj = JSON.parse(comic);

document.querySelector("#simplejson").innerHTML =
   obj.author + "<br>" + 
   obj.book.title + "<br>" + 
   obj.book.published + "<br>" + 
   "<img src='" + obj.book.image + "'>";

Mit XML käme selbst so ein kleines Objekt mit einem Schwall an Overhead. Das Parsen wäre viel komplizierter und fehlerträchtiger.

<comic>
    <author>Peters und Schuiten</author>
    <book>
       <title>Bruesel</title>
       <published>1992</published>
       <image>https://www.mediaevent.de/javascript/img/bruesel.jpg</image>
    </book>
</comic>

JSON.stringify() ist die Umkehrung von parse() und konvertiert ein Javascript-JSON-Objekt in einen String.

JSON und Ajax

Eine perfekte Symbiose: Javascript JSON mit Ajax läd Daten vom Server, ohne die Seite neu zu laden, und ohne die Assistenz einer serverseitigen Anwendung (z.B. PHP). JSON-Daten werden zwar i.d.R. durch eine serverseite Anwendung erzeugt, aber z.B. für das Nachladen von Inhalten in eine Webseite oder App reicht eine einfache Textdatei.

Die kleine Tabelle der Sonderzeichen hier hat nur zwei Tabellenzeilen im Quellcode. Sobald der Benutzer die Seite scrollt, werden weitere Zeilen via JSON und Ajax nachgeladen. Das hält die Ladezeit kurz bei einer langen Tabelle und führt gar nicht erst zu einem Datentransfer, wenn der Benutzer sich nicht für den weiteren Inhalt interessiert.

<table id="symtable">
…
<tr><td>Typo</td><td>" "</td> … </tr>
<tr><td>Satzzeichen</td><td>¡</td> … </tr>
</table>
KategorieZeichenNumerischBeschreibung
Typo" "&#160;nicht brechendes Leerzeichen
Satzzeichen¡&#161;umgekehrtes Ausrufezeichen

Die weiteren Zeilen liegen in einer Textdatei symbols.json:

{
"list" : [
	{ "bats0" : "Dingbats, Pfeil … " },
	{ "bats1" : "Dingbats, Pfeil … " },
	{ "bats2" : "Dingbats, Pfeil … " },
	{ "bats3" : "Dingbats, Pfeil … " } ,
	{ "bats4" : "Dingbats, Pfeil … " }	
	]
}

Das Script feuert, wenn die Tabelle beim Scrollen sichtbar wird – in den Viewport kommt – und meldet das scroll-Event dann wieder ab. Via XMLHttp-Request (Ajax) öffnet das Script die Datei mit dem JSON-Objekt und parst die Daten. Der Bequemlichkeit zuliebe sind hier die Zeilen mitsamt HTML-Markup im JSON-Objekt notiert. Effizienter wäre es natürlich, die einzelnen Zellen jeder Zeile als Array zu notieren und das Markup mit Javascript zu erzeugen. Also, nur damit das Script übersichtlich bleibt …

function isInViewport(element) {
   var rect = element.getBoundingClientRect();
   var html = document.documentElement;
   return (
      rect.top >= 0 &&
      rect.left >= 0 &&
      rect.bottom <= (window.innerHeight || html.clientHeight) &&
      rect.right <= (window.innerWidth || html.clientWidth)
  );
}

window.onscroll = function () {

   if (isInViewport (document.getElementById('onebefore')) ) {
      window.onscroll = null;
      var xhr = new XMLHttpRequest();
      xhr.open ('GET', 'symbols.json');
      xhr.onreadystatechange = function () {
         if ((xhr.status === 200) && (xhr.readyState === 4)) {
            var x = 2; 
            var rows = JSON.parse(xhr.responseText);
            var output = '';
            for (var i = 0; i<= rows.list.length-1; i++) {
               for (key in rows.list[i]) {
                  if (rows.list[i].hasOwnProperty(key)) {
                     output += rows.list[i][key];
                  } // if hasProp
               } // for key
            } // for i
            var update = document.getElementById('symtable');
            update.innerHTML = update.innerHTML + output;
         } // if xhr
      } // onready
      xhr.send();
   }
}

JSON und PHP

JSON wird auch für die Kommunikation mit PHP-Anwendungen auf dem Server eingesetzt. PHP kann JSON direkt auswerten: PHP json_decode wandelt einen JSON-String in eine PHP-Variable um.

JSON IN JAVASCRIPT