Přejít k navigační liště

Zdroják » JavaScript » Nativní podpora JSON v prohlížečích

Nativní podpora JSON v prohlížečích

Rozhraní pro práci s JSON (JavaScript Object Notation) ve webových prohlížečích implementují weboví vývojáři v JavaScriptu. To přináší jisté problémy. Prohlížeče proto začínají implementovat nativní rozhraní pro podporu JSON, které je standardizováno v připravovaném ECMAScriptu 3.1.

Posledně jsme poukázali na bezpečnostní problém, který vzniká, pokud JSON zpracováváme metodou eval. Navíc někdy potřebujeme při JSON zpracování dodatečně upravit. Hodilo by se mít pořádné rozhraní.

Rozhraní pro práci s JSON navrhl samotný tvůrce formátu JSON Douglas Crockford a vytvořil i jeho ukázkovou implementaci v JavaScriptu. Douglas je také členem pracovní skupiny, která připravuje specifikaci nové verze JavaScriptu (ECMAScript 3.1) a rozhraní pro práci s JSON je jednou z jejích novinek.

V prohlížečích se objeví relativně brzy. Je implementováno v Internet Exploreru 8, možná se dočkáme implementace ve Firefoxu 3.1 a pracuje se na implementaci do WebKitu. Jak si poradí vývojáři s tím, že některé prohlížeče budou JSON podporovat a jiné nikoliv?

Kompletní rozhraní pro JSON je implementovatelné i v JavaScriptu. Proto rozdíl mezi prohlížeči dokáží skrýt javascriptové frameworky, jak to ostatně dělají dnes a denně v řadě dalších případů. Nativní podpora v prohlížečích bude zajisté rychlejší, proto ji javascriptové frameworky pravděpodobně brzy začnou využívat, v ostatních prohlížečích ji naopak mohou emulovat vlastní implementací v JavaScriptu. Z pohledu vývojáře bude rozhraní stejné.

Rozhraní pro práci s JSON

Podívejme se, jak rozhraní vypadá. Jeho základem jsou dvě inverzní operace:

  • vytvoření JSON z javascriptové datové struktury (serializace)
  • sestavení javascriptové datové struktury z JSON (parsování, deserializace)

Stringify: vytváříme JSON

Serializaci do formátu JSON provede metoda JSON.stringify. Výraz JSON.stringify({x: 45, y: 21}) vrátí řetězec  '{"x":45,"y":21}'.

Jak metoda stringify pracuje? Všechny datové typy v ECMAScriptu 3.1 mají svou metodu toJSON, např. Number.prototype.toJSON(), která obstará jejich převod do formátu JSON. Pokud chcete vašemu vlastnímu objektu přiřadit jeho reprezentaci v JSON, definujte mu vlastní metodu toJSON.

Pokud metoda stringify nedokáže datovou strukturu převést na JSON, např. když narazí na cyklické odkazy mezi objekty, vyvolá výjimku.

Metodu lze volat i se dvěma volitelnými parametry:  JSON.stringify(value, replacer, space);

Parametr replacer může obsahovat funkci nebo pole. Pokud obsahuje pole, slouží jako filtr – pouze položky, jejichž jména replacer obsahuje, budou uloženy do JSON. Pokud obsahuje funkci, může být použit nejen k filtrování, ale i ke transformaci dat před uložením do JSON. Ta poslouží v případě, že nechceme přepisovat globální toJSON metodu daného objektu, ale potřebuje provést konverzi platnou jen pro daný konkrétní převod.

Parametr space ovlivňuje formátování JSON, resp. jeho čitelnost pro člověka. Pokud je prázdný, bude vygenerovaný JSON formátovaný na jednu řádku, když jej nastavíme na mezeru, bude JSON formátován na více řádek a každý další vnořený objekt bude odsazen o mezeru více (obdobně zafungují dvě mezery, tabulátor apod).

Parsujeme JSON

Inverzní operací k serializaci je parsování JSON a vytvoření datové struktury. To provede metoda JSON.parse. Výraz JSON.parse('{"x": 45, "y": 21}') vrátí objekt {x: 45, y: 21}. Pokud parametrem není platný JSON formát, je vyvolána výjimka SyntaxError.

Metodu můžeme volat i s volitelným parametrem: JSON.parse(value, reviver);

Druhý parametr odkazuje na funkci, která může:

  • provést transformaci dat hned po jejich načtení
  • odfiltrovat některé položky vytvářené datové struktury

Proč provádět transformaci? Na rozdíl od vytváření JSON není jeho parsování vždy jednoznačné, např. řetězec „2008–10–01“ mohl být původně obyčejný řetězec nebo datum. (Pozn.: Datum se do JSON ukládá jako řetězec, viz první díl.) Naše funkce reviver může nejednoznačnosti vyřešit.

Detekce podpory

Pokud chceme detekovat, zda prohlížeč podporuje JSON, postačí ověřit existenci vlastnosti  window.JSON:

if (window.JSON)
  // prohlížeč nativně JSON podporuje
else
  // prohlížeč JSON nepodporuje

O detekci se ovšem zpravidla nebudeme muset starat my, ale framework.

Nedostatky JSON

K formátu JSON se váže i několik nedostatků. Jedná se zejména o tyto dva:

Ne každá datová struktura lze převést na JSON. Strukturu, která obsahuje cyklické odkazy, na JSON nepřevedete. Před převodem do JSON musíte cyklické odkazy odstranit.

JSON nepodporuje odkazy – JavaScript používá v datových strukturách odkazy, ale při serializaci do JSON jsou všechny odkazy vyhodnoceny, serializovaná podoba pole [1, a, a] (pokud a = 2) bude vypadat takto ‚[1,2,2]‘. Pamatujte tedy, že serializací a následným parsováním nemusíte nutně dostat stejnou datovou strukturu, jakou jste měli původně.

JSONRequest

AJAX dnes používá XMLHttRequest, který je, jak již název napovídá, určen k přenosu XML. Vývojáři jej ovšem používají i pro přenos JSON (i my jsme tak učinili v minulém díle). Douglas Crockford navrhl JSONRequest, který by měl sloužit jako náhrada. Funguje velmi podobně, jen se při komunikaci oběma směry vyměňuje JSON.

Ačkoliv je JSONRequest zajímavou myšlenkou, není implementován v žádném prohlížeči, existuje pouze ukázkové rozšíření pro prohlížeč Firefox.

Příklad k vyzkoušení

Pokud máte po ruce prohlížeč Internet Explorer 8, můžete si v něm vyzkoušet nativní podporu JSON v naší ukázkové aplikaci (načte vstupní řetězec s JSON, převede jej na datovou strukturu a zpětně serializuje – všimněte si, jak se může v některých případech vstup a výstup lišit).

Odkazy

Komentáře

Subscribe
Upozornit na
guest
4 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments
deda.jabko

It is a Scheme-like language with C-like syntax.

tak to dopada, kdyz si nekdo k tak hezkemu jazyku vymysli vlastni syntaxi. mimochodem, lisp by nemel problemy ani s tema kruhovyma odkazama… ;-]

Hahaha

Jejda, te zykle budou asi wydloidni. Co / pane LO?

Jakub Vrána

Odkazy zmiňované v článku používá JavaScript jen u objektů, skaláry se ukládají hodnotou. Příklad je tedy zvolen velmi nešťastně. [1, a, a] (pokud a = 2) totiž bude skutečně uloženo jako [1, 2, 2] a změna hodnoty a obsah pole nezmění. Příklad by dával smysl, kdyby a bylo např. {val: 2}.

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.