Javascript JSON

Javascript 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 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.

23-02-02 SITEMAP CSS HTML JS Basis JS Web Tutorial SVG

Weil JSON so einfach ist

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 (besser lesbar als XML, das immer mehr durch JSON ersetzt wird). JSON ist einfach, schnell und erzeugt wenig Overhead.

<library>
  <author>Austen</author>
  <firstname>Jane</firstname>
  <books>
    <book>Sanditon</book>
    <book>Stolz und Vorurteil</book>
    <book>Emma</book>
  </books>
</library>
{
  "author"    : "Austen",
  "firstname"	: "Jane",
  "books"	: [
    "Sanditon", 
    "Stolz und Vorurteil", 
    "Emma"
  ]
}

let  info = JSON.parse(data);
info.books[1]        // Stolz und Vorurteil

Wer sich mit XML-Tags, Namespaces, Attributen und Schemas auseinander setzen muss, erlebt einen komplizierten und zeitaufwändigen Prozess. JSON hingegen gibt den relevanten Daten den Vorzug.

So liegt z.B. die Konfiguration des Code-Editors Bracket (bracket.json) – wie die Namenserweiterung schon sagt – im JSON-Format vor und Twitter ab Version 1.1 auf JSON nicht mehr auf XML setzt.

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
let colors = { farbe : "Gelb"}

Javascript-Object und JSON-Objekte sehen sich sehr ähnlich: Die doppelten 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.

let 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.

let comic = '{"author":"Schuiten und Peters", "book": {"title":"Bruesel", "published":"1992", "image":"https://www.mediaevent.de/javascript/img/bruesel.jpg"}}';
let 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.

Inhalt nachladen mit JSON

Eine perfekte Symbiose: Javascript fetcg 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 für das Nachladen von Inhalten in die Webseite reicht eine einfache JSON-Datei.

Sobald der Benutzer die Seite scrollt, werden die Zeilen via fetch() nachgeladen. Das hält die Ladezeit bei einer langen Tabelle kurz und führt gar nicht erst zu einem Datentransfer, wenn der Benutzer sich nicht für den weiteren Inhalt interessiert.

<div id="symtable"></div>

Die weiteren Zeilen liegen in einer Textdatei symbols.json:

[
   { "name" : "Icon, Schere",   "symbol1" :"✂", "desc" :"Geöffnete Schere" },
   { "name" : "Icon, Pfeil",    "symbol1" :"✆", "desc" :"Telefonhörer, Schnur bildet Kreis" },
   { "name" : "Icon, Flugzeug", "symbol1" :"✈", "desc" :"Flugzeug" },
]

Das Script feuert, wenn die Tabelle beim Scrollen sichtbar wird – in den Viewport kommt – und meldet das scroll-Event dann wieder ab. Via Javascript fetch() öffnet das Script die Datei mit dem JSON-Objekt und parst die Daten (fetch: die elegante Variante der Ajax-Requests).

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

function appendData (data) {
   console.log ("appendData");
   const container = document.querySelector("#symtable");
   for (let i=0; i<data.length; i++) {
      const div = document.createElement ("div");
      div.innerHTML = "<span>" + data[i].name + "</span><span>" + data[i].symbol1 + "</span><span>" + data[i].desc + "</span>";
      container.appendChild (div);
   }
}

window.onscroll = function () {

   if (isInViewport (document.getElementById('onebefore')) ) {
      window.onscroll = null;
      
      fetch ("symbols.json").then (function (response) {
         return response.json();
      }).then (function (data) {
         appendData (data);
      }).catch (function (error) {
         console.log ("Fehler: " + error);
      });
   }
}

Mit node.js kann Javascript JSON direkt speichert, ansonsten muss das Script zum Speichern von JSON auf PHP setzt.

Über ein JSON-Objekt iterieren

JSON hat eine eingebaute rudimentäre Iteration, so dass der Zugriff auf alle Eigenschaften und Werte einfach ist.

const terms = {
   "mit dem Strom schwimmen" : "float with the current",
   "auf hohem Niveau" : "on a high level"
}

for (let prop in terms) {
	console.log (prop, terms[prop]);
}

for-in-Iteration bei Javascript-Objekten

Eleganter: array.map übernimmt Werte aus einem JSON-Array in ein neues Array. Hier liest array.map alle die Werte von Lightroom in ein einfaches Array von Schlüsselwörtern:

const json = [
{
	"filename": "pipette.svg",
	"path": "svg\/icon",
	"rating": "4",
	"urgency": "0",
	"lightroom": "Computer,Icon"
},
{
	"filename": "haushalt-kaffeemaschine.svg",
	"path": "svg\/icon",
	"rating": "0",
	"urgency": "0",
	"lightroom": "Icon,Haushalt"
} …
];

let bags = json.map(a => a.lightroom);
console.log (bags);

Am Rande: Mit der arrow-Funktion spielt IE11 nicht mit!

Nicht ganz so einfach kommt Javascript zugleich an Wert und Schlüssel – das Schlüssel-Wert-Paar –, wenn der Zugriff über den Index laufen soll.

const index = 3;

const key = Object.keys (terms)[index];
value = terms[key];

console.log (key, value);

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 fetch mehrere Dateien über eine PHP-Anwendung 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>