JSON text je jedna hodnota
Celý JSON dokument, ve specifikaci JSON text, je jedna hodnota,
před kterou a za kterou smí být bílé znaky. Nejčastěji je to objekt nebo pole, ale platný
JSON text je i samotný řetězec "text" nebo číslo 42. Starší RFC
4627 povolovalo jen objekt nebo pole; pro API je proto bezpečnější posílat na nejvyšší
úrovni objekt, s ním si poradí i staré knihovny.
| Hodnota | Zápis |
|---|---|
| objekt | { "název": hodnota, … } |
| pole | [ hodnota, hodnota, … ] |
| řetězec | "text" (jen dvojité uvozovky) |
| číslo | -12, 3.14, 1e3 |
| logická hodnota | true, false |
| prázdná hodnota | null |
Objekty a pole
Objekt je ve složených závorkách a obsahuje dvojice název: hodnota oddělené čárkou. Název je vždy řetězec ve dvojitých uvozovkách. Objekt je podle specifikace neuspořádaný: na pořadí dvojic by program neměl záviset, i když ho většina knihoven zachová.
Pole je v hranatých závorkách a obsahuje hodnoty oddělené čárkou. Pořadí v poli je součástí dat. Hodnoty v jednom poli mohou být různého typu, i když v praxi se kvůli zpracování drží jeden typ. Objekty a pole se libovolně vnořují a mohou být prázdné:
{
"faktura": {
"cislo": "FV2026-042",
"polozky": [
{ "kod": "HR-01", "pocet": 2 },
{ "kod": "PO-02", "pocet": 1 }
],
"poznamky": []
}
} Bílé znaky
Mezi hodnotami a kolem znaků { } [ ] : , smí být libovolně mnoho
mezer, tabulátorů a konců řádků (LF i CR). Jiné bílé znaky, třeba nezlomitelná mezera,
povolené nejsou. Odsazení tedy na význam nemá vliv a {"a":1} je totéž co
stejný objekt rozepsaný na víc řádků. Uvnitř řetězců to neplatí, tam se tabulátor a konec
řádku musí zapsat jako \t a \n (viz Řetězce).
Co je a co není platný JSON
JSON vznikl podle JavaScriptu, ale je mnohem přísnější. Všechny ukázky v tabulce jsou ověřené parserem:
| Zápis | Platný JSON? | Proč | Nástroj |
|---|---|---|---|
| {"a": 1} | ano | objekt s jednou dvojicí | Vyzkoušet |
| [1, "dva", true, null] | ano | pole může míchat typy | Vyzkoušet |
| "text" | ano | JSON text může být i samotná hodnota (RFC 8259) | Vyzkoušet |
| 42 | ano | samotné číslo | Vyzkoušet |
| {'a': 1} | ne | řetězce a klíče jen ve dvojitých uvozovkách | Vyzkoušet |
| {a: 1} | ne | klíč musí být řetězec v uvozovkách | Vyzkoušet |
| [1, 2,] | ne | čárka za posledním prvkem není povolená | Vyzkoušet |
| {"a": 1} // poznámka | ne | JSON nezná komentáře | Vyzkoušet |
| {"a": undefined} | ne | undefined není hodnota JSON | Vyzkoušet |
| {"a": True} | ne | literály jsou jen malými písmeny: true, false, null | Vyzkoušet |
Typický ručně psaný soubor a jeho opravená verze:
{
'cislo': 'FV2026-042',
polozky: [1, 2, 3,],
uhrazeno: True, // zaplaceno převodem
} {
"cislo": "FV2026-042",
"polozky": [1, 2, 3],
"uhrazeno": true,
"poznamka": "zaplaceno převodem"
} Pokud potřebuješ komentáře nebo čárky navíc, nejde o JSON, ale o rozšíření jako JSONC nebo JSON5. Standardní parser takový soubor odmítne.
Duplicitní klíče
Gramatika JSON duplicitní názvy v jednom objektu nezakazuje, RFC 8259 jen doporučuje (SHOULD), aby byly jedinečné. Chování parserů pak specifikace označuje za nepředvídatelné: některé vrátí poslední hodnotu, jiné první, ohlásí chybu nebo vrátí obě. Změřené chování (Node.js 25, Python 3.14 a PHP 8.4):
| Vstup | JavaScript | Python | PHP |
|---|---|---|---|
| {"a":1,"a":2} | {"a":2} | {'a': 2} | ['a' => 2] |
Všechny tři vrátí poslední hodnotu, na jiné knihovně to ale záviset nemusí. Problém nastane, když stejný dokument čtou dva různé parsery, třeba kontrola na bráně a aplikace za ní: každý může vidět jinou hodnotu. Přísnější profil I-JSON (RFC 7493) duplicitní názvy zakazuje (MUST NOT). Generuj JSON knihovnou a duplicitní klíče nikdy nepoužívej.
Kódování a BOM
JSON vyměňovaný mezi systémy musí být v UTF-8 (RFC 8259, § 8.1). Starší specifikace připouštěly i UTF-16 a UTF-32, v praxi se ale ujalo jen UTF-8. Značka BOM se na začátek JSON textu přenášeného po síti přidávat nesmí; parser ji smí ignorovat, ale nemusí. Testované parsery ji neignorují a skončí chybou:
| Vstup | JavaScript | Python | PHP |
|---|---|---|---|
| [BOM]{"a":1} | chyba | chyba | chyba |
Soubor s BOM, typicky uložený v editoru na Windows, ulož znovu jako „UTF-8 bez BOM“, nebo
BOM před parsováním odstraň (v Pythonu kódováním utf-8-sig).
Rozšíření a limity parserů
Specifikace parseru dovoluje přijímat i zápisy mimo JSON. Proto Python ve výchozím
nastavení přijme NaN nebo Infinity, které platný JSON nejsou.
Parser si také smí nastavit limity: maximální velikost textu, hloubku vnoření, rozsah čísel
a délku řetězců. U dat z cizích zdrojů je rozumné limity nastavit vědomě, například hloubku
vnoření v PHP třetím parametrem json_decode().
Doporučené postupy
- JSON vytvářej knihovnou (
JSON.stringify,json.dumps,json_encode), ne skládáním řetězců. - Klíče v objektu drž jedinečné a nespoléhej na jejich pořadí.
- Ukládej a posílej v UTF-8 bez BOM, s MIME typem
application/json. - U API dávej na nejvyšší úroveň objekt; přidat do něj později další pole nic nerozbije.
- Hotový dokument zkontroluj ve validátoru, strukturu dat pak hlídá JSON Schema.