Javascript JSON

JSON Datenaustausch zwischen Client und Server und Metadaten mit JSON LD Notation

JSON steht für Javascript Object Notation und ist ein Textformat für den Austausch von Daten zwischen Client und Server und zwar zwischen der eigenen Webseite und ihrem Webspace oder mit anderen Diensten wie Twitter. JSON lädt Bilder oder Texte nach und kommuniziert mit der Formularanwendung auf dem Server.

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.

So liegt z.B. die Konfiguration des Code-Editors Bracket (bracket.json) – wie die Namenserweiterung schon sagt im JSON-Format vor.

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.

Ohne großen Aufwand kann Ajax2 mehrere Dateien auf den Server laden.

JSON-LD für Metadaten

Am Ende wird JSON auch für Rich Snippets benutzt – zusätzliches, nicht sichtbares Markup für Metadaten in HTML-Seiten. Die JSON-LD Javascript-Notation wird wie ein script-Tag im head oder body-Element der Seite eingebettet.

Das hat gegenüber den verstreuten HTML-Attributen wie itemprop Vorteile: Das Markup sitzt nicht in den sichtbaren Elementen der Seite, JSON-LD stellt Informationen kompakter zusammen als lange Listen von Metatags, und hierarchisch verschachtelte Elemente wie Land, Postanschrift oder Veranstaltungen lassen sich anlegen. Die Metadaten werden übersichtlicher.

<script type="application/ld+json">
{
  "@context": "http://schema.org",
  "@type": "WebPage",
  "headline": "7 Tipps für Fotos mit Blitz bei Sonnenschein und Gegenlicht",
  "datePublished": "2013-04-05",
  "dateModified": "2018-01-01",
  "lastReviewed": "2018-03-13",
  "potentialAction": { 
    "@type": "SearchAction", 
    "target": "https://ivent.de/webscout/search.php?query={search_term}", 
    "query-input": "required name=search_term" },
  "image" : [
  	"https://ivent.de/assets/foto-mit-blitz/lead.jpg"
  ]
}
</script>
JSON IN JAVASCRIPT