Errori comuni nel JSON e come correggerli
JSON è il formato che molte API, file di configurazione e applicazioni web usano per scambiarsi dati, e la sua grammatica sta in una sola pagina. È anche per questo che non perdona: un testo o è JSON valido o non lo è, e basta una virgola fuori posto perché un parser lo rifiuti per intero. La maggior parte degli errori nasce dalle stesse poche abitudini, molte delle quali ereditate da JavaScript o da altri linguaggi. Questa guida elenca le regole, gli errori che le violano più spesso, come leggere il messaggio di errore e alcuni casi che sono JSON valido ma creano comunque problemi.
Le regole che JSON ha davvero
Le definizioni attuali sono la RFC 8259, pubblicata nel dicembre 2017, e l’ECMA-404. Descrivono la stessa sintassi:
- Le stringhe, compreso ogni nome di proprietà, usano le virgolette doppie. Gli apici singoli non sono ammessi.
- I valori sono stringhe, numeri, oggetti, array o uno di tre letterali: true, false e null, sempre in minuscolo.
- Gli elementi di oggetti e array sono separati da virgole, senza virgola dopo l’ultimo.
- I numeri si scrivono in forma decimale, senza zeri iniziali, senza segno più e senza NaN né Infinity.
- All’interno di una stringa, le virgolette doppie, la barra rovesciata e i caratteri di controllo come l’a capo devono essere scritti come sequenze di escape.
- Non esiste una sintassi per i commenti.
Tra un token e l’altro sono ammessi solo quattro caratteri di spaziatura: spazio, tabulazione, avanzamento riga e ritorno carrello.
Gli errori più comuni
Ognuno di questi viene rifiutato da un parser standard. La correzione è nella descrizione.
{"name": "Ana",}Virgola finale: togli la virgola dopo l’ultimo elemento di un oggetto o di un array.{'name': 'Ana'}Apici singoli: usa le virgolette doppie per i nomi delle proprietà e per le stringhe.{name: "Ana"}Nome di proprietà senza virgolette: ogni nome deve essere una stringa tra virgolette doppie.{"a": 1 "b": 2}Virgola mancante tra due elementi, spesso dopo aver copiato e unito delle righe.{“name”: “Ana”}Virgolette tipografiche, che gli elaboratori di testo e le app di chat inseriscono automaticamente: sostituiscile con le virgolette dritte ".{"note": 1 // total}I commenti non fanno parte di JSON: eliminali, oppure sposta la nota in una proprietà.{"active": True}Letterali con la maiuscola: scrivi true, false e null in minuscolo.{"value": undefined}undefined, NaN e Infinity esistono in JavaScript ma non in JSON: usa null o una stringa.{"code": 007}Gli zeri iniziali non sono ammessi nei numeri: scrivi 7, oppure "007" come stringa se gli zeri contano.{"path": "C:\Users"}Una barra rovesciata singola apre una sequenza di escape, e \U non lo è. Peggio ancora, C:\new verrebbe accettato e letto come C:, un a capo ed ew. Scrivi \\ per una barra rovesciata letterale.{"items": [1, 2}Una parentesi mai chiusa o chiusa con il carattere sbagliato: ogni { richiede una } e ogni [ richiede una ].
Leggere il messaggio di errore
Un parser legge il testo da sinistra a destra e si ferma al primo carattere che non può accettare, quindi la posizione indicata nel messaggio di errore è il punto in cui si è arreso, che spesso si trova subito dopo l’errore vero e proprio. Con una virgola finale, il parser si lamenta della parentesi graffa di chiusura, perché dopo una virgola si aspetta un altro nome di proprietà. Con una parentesi mancante, l’errore può comparire proprio alla fine del testo, lontano dal punto in cui avrebbe dovuto trovarsi la parentesi.
La formulazione cambia da un browser all’altro e da un linguaggio all’altro, e molti messaggi indicano una posizione, anche se non tutti, come numero di caratteri dall’inizio oppure come riga e colonna. Per esempio, il motore JavaScript di Chrome segnala {"name":"Ana",} così:
Expected double-quoted property name in JSON at position 14 (line 1 column 15)Contando da 0, la posizione 14 è la parentesi graffa di chiusura; la virgola che ha causato l’errore si trova un carattere prima.
Quando la posizione non è chiara, guarda il carattere subito prima e controlla che ogni parentesi e ogni virgoletta aperte prima di quel punto abbiano la loro controparte. Un editor che evidenzia le parentesi corrispondenti spesso rende facile individuare quella mancante.
JSON valido che crea comunque problemi
- Numeri grandi. JSON in sé non fissa alcun limite, ma JavaScript, e molti parser JSON di altri linguaggi, memorizzano i numeri in virgola mobile a 64 bit, che garantisce interi esatti solo fino a 9.007.199.254.740.991. In JavaScript, JSON.parse trasforma 9007199254740993 in 9007199254740992 senza alcun avviso. Gli ID grandi sono più sicuri come stringhe.
- Nomi di proprietà duplicati. La RFC 8259 afferma che i nomi dovrebbero essere unici e che il software che riceve duplicati si comporta in modo imprevedibile. JavaScript conserva l’ultimo valore: {"a": 1, "a": 2} diventa {"a": 2}.
- Un byte order mark. Alcuni editor salvano i file UTF-8 con un carattere invisibile U+FEFF all’inizio. La RFC 8259 vieta di aggiungerlo al JSON trasmesso in rete, e JSON.parse di JavaScript rifiuta un testo che inizia con quel carattere.
- Un valore isolato al primo livello. Gli standard attuali (ECMA-404, e la RFC 7159 dal 2014 in poi) consentono che un testo JSON sia un valore qualsiasi, come "hello" o 42, ma la precedente RFC 4627 del 2006 richiedeva un oggetto o un array, e alcuni parser più vecchi lo richiedono ancora.
JSON non è JavaScript
La sintassi di JSON è stata ripresa dai letterali oggetto di JavaScript, ed è per questo che i due si confondono così facilmente. Un letterale oggetto JavaScript accetta apici singoli, nomi senza virgolette, virgole finali, commenti e valori come undefined; JSON non accetta nessuna di queste cose. Il codice che funziona quando lo incolli in uno script può quindi fallire come file JSON.
Alcuni strumenti accettano formati estesi come JSON5, o il «JSON con commenti» per i file di configurazione. Sono comodi dove sono supportati, ma non sono JSON, e un parser standard, compreso il formattatore di nTools, li rifiuterà.
Domande frequenti
JSON può contenere commenti?
No. La specifica non prevede alcuna sintassi per i commenti. Se ti servono delle note nei dati, mettile in una proprietà come "_comment", oppure usa un formato che ammette i commenti, dove gli strumenti lo supportano.
Perché il mio JSON funziona in JavaScript ma non passa la verifica di un validatore?
Perché un letterale oggetto JavaScript ammette cose che JSON non ammette, come apici singoli, virgole finali e nomi senza virgolette. Incollato nel codice funziona; salvato come JSON non è valido.
Come faccio a mantenere esatto un numero molto grande?
Invialo come stringa, per esempio "9007199254740993", e convertilo dal lato di chi lo riceve con un tipo in grado di contenerlo, come BigInt in JavaScript.
Il formattatore di nTools invia il mio JSON da qualche parte?
No. Viene analizzato e formattato nel tuo browser e, quando il browser indica una posizione, il formattatore la mostra come riga e colonna.
Guide correlate
- Indirizzi IP spiegati: IPv4, IPv6 e gli intervalli riservati
- Sottoreti e CIDR spiegati: prefissi, maschere e host utilizzabili
- Record DNS spiegati: A, AAAA, CNAME, MX, TXT e NS
- Timestamp Unix e fusi orari spiegati
- Formati immagine spiegati: JPEG, PNG, WebP, AVIF e HEIC
- Robustezza delle password spiegata: lunghezza, entropia e passphrase
- Gli UUID spiegati: v4, v7 e come scegliere la versione giusta
- I codici QR spiegati: capacità, correzione degli errori e dimensioni di stampa
- Percentuali e IVA spiegate: aggiungere, scorporare e cumulare
- Modificare i PDF nel browser: cosa conservano unione, divisione e conversione