Vai al contenuto
OneKitly

JSON è più semplice di quanto pensi, ed è questo il problema

Pubblicato il 08/08/2025 · 19 min di lettura · Strumenti per sviluppatori

Daniel Okonkwo

Daniel OkonkwoSviluppatore front-end e redattore Tech presso OneKitly

Performance web · Formati di file

Verificato su 7 fonti

Vedi il profilo
In breve

La grammatica di JSON sta in una pagina, ed è esattamente per questo che perde. ECMA-404 e la RFC 8259 definiscono sei specie di valore — oggetto, array, stringa, numero, true o false, null — e nient'altro. Non esiste un tipo intero: JSON ha un solo tipo numerico, e un analizzatore JavaScript lo posa su un double IEEE 754, così 1234567890123456789 torna come il double 1234567890123456768, un errore di 21, mentre l'analizzatore di Python lo restituisce esatto. Stessi byte, due valori diversi. Non esiste un tipo data: un timestamp è una stringa il cui formato è una convenzione. NaN e Infinity non si possono scrivere — JSON.stringify li trasforma in null e JSON.parse rifiuta i letterali, benché il modulo json di Python li emetta per impostazione predefinita producendo documenti che non sono JSON. Lo zero negativo sopravvive in modo asimmetrico: analizzare -0 dà -0, ma serializzare -0 dà 0. Le chiavi duplicate sono legali nella grammatica, la RFC 8259 dice soltanto che il risultato è imprevedibile, e ogni analizzatore diffuso tiene in silenzio l'ultima. I commenti non sono affatto nella grammatica. Uno JSON Schema generato fissa la forma, mai il significato, e quello dedotto da un solo campione sovradatta pesantemente. E l'ordine delle chiavi è un fatto a livello di byte: scambiane due e il payload produce un hash diverso, il che rompe le firme.

JSON non ha un tipo intero, né un tipo data, né commenti, né schema. Ognuna di queste assenze produce un bug preciso: un identificatore di 19 cifre torna sbagliato di 21, un timestamp diventa una stringa su cui nessuno si è accordato, NaN non si può scrivere e le chiavi duplicate sono legali. Tutto eseguito, in due linguaggi.

Sei specie di valore, e nessuna è quella che volevi

JSON è specificato due volte, da ECMA-404 e dalla RFC 8259, ed entrambi i documenti sono brevi perché c'è pochissimo da dire. Un valore è un oggetto, un array, una stringa, un numero, il letterale true, il letterale false o il letterale null. Questo è l'intero sistema di tipi. Tutto il resto che credi ci sia in JSON è stato aggiunto dal tuo linguaggio all'ingresso o all'uscita.

Conta le assenze. Nessun tipo intero, solo un'unica produzione numerica che l'analizzatore deve proiettare sul tipo numerico di cui dispone. Nessuna data, nessuna ora, nessuna durata. Nessun binario — ottieni base64 dentro una stringa, che costa un terzo di byte in più. Nessun commento. Nessuna enumerazione, nessun intervallo, nessun campo obbligatorio, nessuno schema. Nessuna garanzia sull'ordine delle chiavi. Nessun modo di esprimere un riferimento a un'altra parte dello stesso documento: un grafo va appiattito a mano.

Niente di tutto ciò è un difetto di progetto. JSON è stato estratto da una sintassi letterale JavaScript per spostare dati fra due programmi già d'accordo su cosa i dati significassero, e svolge quel compito con una dimensione e una velocità che nulla ha battuto. Il difetto compare quando un formato che non trasporta significato viene usato come se ne trasportasse. Tutto ciò che segue è un'istanza di quell'errore.

Il numero che torna sbagliato

La grammatica numerica di JSON accetta qualsiasi decimale tu sappia scrivere. La RFC 8259 avverte che le implementazioni variano e raccomanda di restare nella doppia precisione IEEE 754, il che in pratica significa interi fino a 2^53 − 1 = 9 007 199 254 740 991. Oltre, i double non riescono più a rappresentare interi consecutivi, e un analizzatore JavaScript non ha altro posto dove mettere il valore.

Eseguilo. JSON.parse('9007199254740993') restituisce 9007199254740992 — l'ingresso era dispari, l'uscita è pari, e nessun errore è stato sollevato. Prendi un identificatore realistico a 19 cifre del tipo che distribuiscono le piattaforme sociali e i servizi di messaggistica: JSON.parse('{"id": 1234567890123456789}') memorizza il double 1234567890123456768, che JavaScript poi stampa come 1234567890123456800 perché è il decimale più corto che torna allo stesso double. L'identificatore ricevuto differisce da quello memorizzato di 21, e da quello stampato di 32. Un id più corto a 18 cifre, 175928847299117063, torna come 175928847299117060.

Ora dai gli stessi identici byte a Python 3.13: json.loads restituisce esattamente 1234567890123456789, come int di Python, perché l'analizzatore di Python proietta la produzione numerica JSON su un intero a precisione arbitraria quando non c'è parte frazionaria. Un documento, due linguaggi, due valori diversi, ed entrambi gli analizzatori sono conformi. È tutto il problema in una riga: JSON non dice a un analizzatore quale tipo numerico usare, quindi l'analizzatore decide, e la decisione non è la stessa ovunque.

Lo stesso buco inghiotte la distinzione intero/decimale nell'altro verso. JSON.stringify(1.0) produce i due caratteri "1", perciò un campo che il tuo database ha dichiarato decimale arriva come qualcosa che un generatore di schemi etichetterà intero. Non c'è modo di scrivere 1.0 in JSON e vederlo restare 1.0 dopo un giro di andata e ritorno in JavaScript. Il rimedio per gli identificatori è brusco e universale: mandali come stringhe. Le piattaforme morse presto consegnano entrambi i campi — un id numerico e un id testuale — proprio perché non potevano correggere i loro client.

Date, NaN, Infinity e un segno meno che sparisce

JSON.stringify(new Date(...)) produce "2026-08-28T14:30:00.000Z", il che sembra dire che JSON capisca le date. Non le capisce. ECMAScript definisce Date.prototype.toJSON, e JSON.stringify lo invoca; il risultato è una stringa ordinaria. Rianalizzala e typeof dà "string". Il formato è per caso quello che la RFC 3339 ritaglia da ISO 8601, ma nulla in JSON lo impone, e appena un secondo servizio serializza con un'altra libreria ottieni una data di altra forma — un intero epoch, un'ora locale senza scostamento, un involucro "/Date(1234567890)/" da uno stack più vecchio. Ognuna è JSON altrettanto valido e altrettanto illeggibile senza un accordo preliminare.

NaN e i due infiniti non sono nella grammatica, quindi non si possono proprio scrivere. JSON.stringify({a: NaN, b: Infinity, c: -Infinity}) restituisce {"a":null,"b":null,"c":null} — tre valori in virgola mobile distinti collassati in un solo null, in silenzio. JSON.parse('{"a":NaN}') solleva un SyntaxError. Dentro un array anche undefined, le funzioni e i simboli diventano null; come valori di oggetto vengono eliminati del tutto, così {a: undefined, b: 1} si serializza in {"b":1} e una chiave semplicemente sparisce.

Python fa qualcosa di peggiore e più interessante: json.dumps({'a': nan, 'b': inf}) emette per impostazione predefinita {"a": NaN, "b": Infinity}, e json.loads lo rilegge senza batter ciglio. Quell'uscita non è JSON. Attraverserà i tuoi servizi Python intatta e fallirà appena raggiungerà un analizzatore conforme in un altro linguaggio qualsiasi, che di solito è il browser, che di solito è la produzione. L'opzione esiste — allow_nan=False solleva un'eccezione — e quasi nessuno la imposta.

Lo zero negativo è il più piccolo e il più strano del gruppo. IEEE 754 ha due zeri, e contano dove un segno porta informazione — un tasso di variazione, un verso di arrotondamento, un saldo arrivato esattamente a nulla da sotto. JSON.parse('-0') restituisce -0: Object.is(JSON.parse('-0'), -0) è true, e 1 diviso per esso dà −Infinity. Ma JSON.stringify(-0) restituisce il solo carattere 0. Il valore sopravvive quindi in un verso e non nell'altro, e un giro completo ribalta 1 ÷ x da −Infinity a +Infinity senza il minimo avviso.

Le chiavi duplicate sono legali, e ogni analizzatore ne sceglie una in silenzio

La grammatica JSON definisce un oggetto come una sequenza di coppie nome-valore separate da virgole. Non dice che i nomi debbano differire. La RFC 8259 affronta la cosa in prosa anziché nella grammatica: i nomi DOVREBBERO essere unici, e avverte che le implementazioni davanti a un duplicato si comportano diversamente — alcune prendono l'ultima, alcune la prima, alcune segnalano un errore. Quel DOVREBBERO è la parola più debole che la RFC potesse usare, e significa che qualsiasi analizzatore incontrerai accetta il documento.

In pratica il grosso ha convergito. JSON.parse('{"role":"admin","role":"user"}') restituisce {"role":"user"} in Node, e json.loads di Python restituisce lo stesso. Vince l'ultima, senza avvisi, senza modo di rilevare a posteriori che il documento ne aveva due. L'informazione che esisteva un duplicato viene distrutta dall'analisi stessa, ed è ciò che rende difficile il debug: quando il tuo codice vede l'oggetto, la prova non c'è più.

La conseguenza da prendere sul serio è che un documento può significare una cosa per il componente che lo controlla e un'altra per quello che agisce, se i due componenti usano analizzatori che non concordano — o se uno ispeziona il testo grezzo e l'altro l'oggetto analizzato. La forma generale di questo pericolo e la regola che ne discende sono trattate nell'articolo di questo sito sulla verifica dei token firmati: convalida e agisci sulla stessa rappresentazione analizzata, mai su due. La mitigazione concreta qui è più semplice. Rifiuta i documenti con nomi duplicati all'ingresso, prima che qualsiasi altra cosa li guardi; un analizzatore a flusso o una passata di tokenizzazione preliminare vede il duplicato che JSON.parse butta via.

Cosa dà uno schema generato, e dove sovradatta

JSON Schema copre il buco più grande: è un vocabolario per dire quali chiavi devono esistere, che tipo ha ciascun valore, quali valori sono ammessi e quanto in profondità arriva l'annidamento. Un validatore trasforma un documento informe in un sì o un no al confine del tuo sistema, e vale molto. Generare una prima bozza da un campione che hai già è la via più rapida, ed è ciò che fa il generatore di schemi di questo sito.

La trappola è che uno schema dedotto da un solo documento descrive quel documento, non la famiglia a cui appartiene. Prendi un campione dall'aria innocua: un oggetto con un id intero pari a 42, un nome, un array di un solo tag testuale, uno score intero di 10, un manager che per caso è null e un booleano. Un generatore ingenuo produce tipo integer per id e score, tipo null per manager, array di stringhe per tags, tutte le chiavi in required e additionalProperties a false.

Ora convalida contro di esso cinque documenti successivi perfettamente legittimi. Uno score che arriva come 10.5 viene rifiutato, perché il campione era intero. Un manager finalmente riempito con un oggetto viene rifiutato, perché il campione era null. Un documento che omette un campo facoltativo viene rifiutato, perché il generatore ha messo tutte le chiavi in required. Un documento con un nuovo campo email viene rifiutato, perché additionalProperties era false. Un array tags contenente un numero viene rifiutato. Cinque su cinque, e ognuno è un record reale che il tuo sistema avrebbe dovuto accettare.

L'altra metà della lezione è ciò che lo stesso schema accetta volentieri: un record con nome vuoto e uno score di −999 supera ogni controllo, perché JSON Schema convalida la forma e mai il significato. Nulla nel vocabolario sa che un nome dovrebbe essere non vuoto o che uno score ha un pavimento. Usa quindi la generazione come prima bozza e poi correggila a mano: allarga integer a number ovunque sia possibile un decimale, sostituisci un tipo null con un'unione nullable, riduci required ai campi davvero obbligatori, lascia additionalProperties aperto a meno che tu non stia chiudendo il contratto di proposito, e aggiungi i vincoli minLength, minimum ed enum che portano le tue vere regole di business.

L'ordine delle chiavi e la firma che smette di combaciare

Gli oggetti JSON sono non ordinati come modello di dati, ma un documento JSON è una sequenza di byte e i byte hanno un ordine. JSON.stringify emette le chiavi testuali in ordine di inserimento — con un'eccezione che coglie in fallo. ECMAScript mette per prime le chiavi con indice intero, in ordine crescente, davanti a ogni chiave testuale. Costruisci un oggetto assegnando z, poi user_2, poi "2", poi user_1, poi "1": stringify restituisce {"1":5,"2":3,"z":1,"user_2":2,"user_1":4}. Le due chiavi dall'aspetto numerico sono balzate in testa e si sono ordinate numericamente; il resto è rimasto nell'ordine scritto. L'analisi fa lo stesso, quindi un documento ricevuto in un ordine esce da JSON.parse in un altro.

Diventa un incidente di produzione appena calcoli l'hash di un payload. Due servizi descrivono lo stesso bonifico da 100 €: uno scrive {"amount":100,"currency":"EUR","to":"acct_9"} e l'altro gli stessi tre campi partendo da "to". Gli oggetti sono profondamente uguali. I digest SHA-256 valgono 1648f3b9016a5b95… e bc654befe505d093…, e un HMAC calcolato su ciascuno differisce dal primo byte. Il destinatario rifiuta una richiesta che è, semanticamente, esattamente quella che si aspettava.

Ordinare le chiavi prima di serializzare risolve questo caso specifico — entrambi gli oggetti si canonizzano nella forma che inizia con amount e i digest coincidono. Ma ordinare da solo non è una forma canonica, perché lo stesso valore può ancora essere scritto in più modi: "é" e "\u00e9" sono la stessa stringa e byte diversi, 1e21 e 1000000000000000000000 sono lo stesso numero, e un serializzatore può o meno effettuare l'escape della barra. La RFC 8785, JSON Canonicalization Scheme, è la risposta normalizzata: fissa l'ordine delle chiavi per unità di codice UTF-16, lega la formattazione dei numeri alle regole ECMAScript e definisce esattamente quali caratteri vengono sottoposti a escape. Se puoi evitare del tutto il problema, evitalo: firma e verifica gli esatti byte che hai ricevuto, e non riserializzare mai un documento che stai per controllare.

La lista pratica

Manda ogni identificatore come stringa, qualunque sia il suo tipo nel tuo database. Concordate per iscritto un solo formato di timestamp — la RFC 3339 con scostamento esplicito è il meno controverso — e rifiuta tutto il resto al confine invece di indovinare. Decidi in anticipo cosa significa un valore mancante, e scegli o null o l'assenza, non entrambi. Non lasciare mai che un NaN o un infinito raggiunga un serializzatore: convertilo in null, in stringa o in errore, deliberatamente, là dove avviene il calcolo.

Rifiuta i nomi duplicati all'ingresso. Genera uno schema per risparmiare battute, poi correggilo prima di fidartene. Canonizza, oppure firma i byte grezzi, mai un oggetto riserializzato. E tieni i file di configurazione, dove gli umani hanno bisogno di commenti e virgole finali, in un formato che li abbia — che è il tema dell'articolo successivo.

Lo stesso documento JSON letto da due analizzatori conformi — Node v26.3.0 e Python 3.13.2
Nel documentoNode restituiscePython restituisceConseguenza
900719925474099390071992547409929007199254740993 (esatto)Un numero dispari diventa pari, senza errore
12345678901234567891234567890123456768, stampato come 12345678901234568001234567890123456789 (esatto)Identificatore sbagliato di 21; i due servizi divergono
1.01, e JSON.stringify lo riscrive come "1"1.0 come float, riscritto come 1.0Distinzione decimale/intero persa in un solo linguaggio
Una Date serializzata, "2026-08-28T14:30:00.000Z"Una stringa (typeof è "string")Una stringaNon esiste un tipo data; il formato è una convenzione
NaN scritto come letteraleSyntaxError — rifiutatonan — accettato, ed emesso per impostazione predefinitaPython scrive documenti che non sono JSON
-0 serializzato da un programmaScritto 0; il segno è sparitoScritto -0.0; il segno sopravvive1 ÷ x passa da −Infinity a +Infinity
{"role":"admin","role":"user"}role = user (vince l'ultimo)role = user (vince l'ultimo)Grammatica legale, imprevedibile secondo la RFC 8259
Generatore di JSON SchemaTrasforma un campione di JSON in un JSON Schema. Incolla un oggetto, un array o record per riga: deduce i tipi, le proprietà e la forma degli array, unisce i campi visti negli oggetti in una lista di obbligatori, e riconosce formati stringa comuni — email, URL, UUID, data e data-ora — in Draft 2020-12, 2019-09 o Draft-07.Prova lo strumento

Domande frequenti

Come faccio passare un identificatore a 64 bit attraverso JSON senza perdere cifre?
Mandalo come stringa. È l'unico rimedio che funziona ovunque, ed è il motivo per cui le piattaforme morse per prime pubblicano due campi — un id numerico e una versione testuale dello stesso id — invece di rompere i loro client. Un reviver di JSON.parse non ti aiuterà: il reviver gira dopo che il tokenizzatore ha già prodotto il double, quindi quando la tua callback vede il valore le cifre sono già andate. Esistono analizzatori compatibili con bigint e funzionano davvero, perché leggono il testo del token e decidono il tipo da soli, ma cambiano ciò che il tuo codice riceve e ogni confronto, JSON.stringify e operazione aritmetica a valle va verificato. Se non puoi cambiare il produttore, rileva almeno il danno: un intero il cui valore assoluto supera Number.MAX_SAFE_INTEGER, 9007199254740991, non è più affidabile, e un giro tramite String(BigInt(x)) confrontato col token grezzo ti dirà se è sopravvissuto. E quando passi alle stringhe, ricorda che un identificatore testuale si ordina lessicograficamente: "10" viene prima di "9", quindi ogni ordinamento su cui contavi deve spostarsi in un campo numerico separato o nel database.
Le chiavi duplicate sono davvero JSON valido?
Sì, grammaticalmente. Né ECMA-404 né la grammatica della RFC 8259 vietano un nome ripetuto, quindi un documento che ne contenga uno si analizza. La RFC 8259 aggiunge un requisito in prosa a livello DOVREBBE — i nomi dovrebbero essere unici — e avverte che le implementazioni divergono quando non lo sono, elencando tre comportamenti plausibili: tenere l'ultimo, tenere il primo, o segnalare un errore. Misurato qui, JSON.parse di Node e json.loads di Python tengono entrambi l'ultimo, così {"role":"admin","role":"user"} dà il ruolo user in entrambi. Poiché l'analisi stessa scarta la prova, non puoi rilevare il duplicato dall'oggetto risultante, e nessuna convalida successiva lo troverà. La regola pratica è rifiutare all'ingresso: o un analizzatore a flusso o basato su eventi che segnali ogni nome man mano che compare, o una passata di tokenizzazione economica che conti i nomi per oggetto, e rifiuti la richiesta. Uno schema non lo farà al posto tuo — JSON Schema opera sull'istanza analizzata, quando il duplicato è già stato risolto.
JSON non ha commenti. Cosa uso per i file di configurazione?
I commenti sono stati esclusi di proposito, sul ragionamento che la gente vi avrebbe messo direttive di analisi. Le virgole finali, le stringhe con apici singoli e le chiavi senza virgolette mancano per la stessa ragione: la grammatica è piccola perché ogni implementazione concordi. È una buona proprietà per i dati in transito e pessima per un file che un umano mantiene. La divisione onesta è usare JSON stretto per tutto ciò che una macchina produce o trasmette, e qualcosa di più accogliente per tutto ciò che una persona modifica. JSONC — JSON con commenti — è ciò che vari editor e catene di strumenti accettano, ed è il passo più piccolo di lato. JSON5 aggiunge virgole finali, chiavi senza virgolette, apici singoli, numeri esadecimali e i letterali NaN e Infinity che a JSON mancano. TOML è progettato specificamente per la configurazione e ha date vere. YAML è il più diffuso ed è il tema dell'articolo successivo di questa serie, comprese le maniere in cui la sua inferenza di tipi ti sorprenderà. L'unica cosa da non fare è una chiave "_comment": è legale, sopravvive ai giri di andata e ritorno, e sopravvive anche in ciò che serializzi dopo, dove nessuno se l'aspetta.
Uno schema generato sostituisce la convalida scritta a mano?
No, per due ragioni distinte. Primo, la generazione sovradatta: misurato sopra, uno schema dedotto da un singolo record ha rifiutato cinque record successivi legittimi su cinque — un decimale dove il campione aveva un intero, un campo popolato dove il campione aveva null, un opzionale assente, un campo aggiunto e un array a tipi misti. Ognuno è una normale evoluzione di un payload reale. Secondo, JSON Schema convalida la forma e non il significato per progetto, quindi lo stesso schema ha accettato senza fiatare un record con nome vuoto e uno score di −999. Ciò per cui la generazione serve davvero è la parte noiosa: enumerare cinquanta chiavi e i loro tipi senza un refuso, e darti un file di partenza che già si analizza. Tratta l'uscita come una bozza e fai quattro correzioni prima di fidartene — allarga integer a number ovunque possa comparire un decimale, rendi i campi nullable un'unione invece del tipo null, pota required a ciò che è davvero obbligatorio, e decidi consapevolmente se additionalProperties debba essere false. Aggiungi poi i vincoli che portano le regole di business, perché sono esattamente quelli che nessun generatore può dedurre dai dati.
Perché due servizi calcolano hash diversi dello stesso payload?
Perché un hash è sui byte e i due servizi hanno prodotto byte diversi per lo stesso valore. Tre cose variano indipendentemente. L'ordine delle chiavi è il colpevole abituale: due oggetti profondamente uguali si serializzano diversamente se le loro chiavi sono state inserite in un ordine diverso, e ECMAScript inoltre issa in testa le chiavi dall'aspetto di indice intero in ordine numerico crescente, così "2" e "10" passano davanti a tutte le altre indipendentemente da dove le hai scritte. L'escape delle stringhe è il secondo: "é" scritto direttamente e scritto \u00e9 sono la stessa stringa e byte diversi, e i serializzatori non concordano sull'escape della barra e dei due separatori di riga U+2028 e U+2029. La formattazione dei numeri è il terzo: 1e21 e la sua forma decimale lunga denotano lo stesso double, e 1.0 si serializza come 1. Il rimedio giusto dipende da dove ti trovi. Se stai verificando qualcosa che hai ricevuto, fai l'hash degli esatti byte arrivati e non riserializzarli mai, cosa che aggira tutti e tre i problemi in un colpo. Se devi calcolare l'hash di un valore costruito da te, usa una forma canonica definita: la RFC 8785 ne specifica una che fissa insieme ordine delle chiavi, formattazione dei numeri ed escape, e ci sono librerie che la implementano nella maggior parte dei linguaggi.
JSON.parse è sicuro su input non fidato?
Strutturalmente sì, e assai più sicuro dell'eval che ha sostituito: la grammatica non contiene alcun costrutto eseguibile, quindi un documento analizzato non può eseguire codice. Emergono due preoccupazioni concrete ed entrambe sono meno allarmanti della loro fama. L'inquinamento del prototipo non è causato da JSON.parse — la specifica impone di creare proprietà dati, perciò JSON.parse('{"__proto__": {"admin": true}}') dà un oggetto con una comune proprietà propria chiamata __proto__ e lascia Object.prototype intatto; verificato qui, ({}).admin resta undefined. L'inquinamento avviene dopo, in una fusione ricorsiva ingenua o in un ciclo di assegnazione non protetto che percorre quelle chiavi: è lì che va la guardia. Anche l'overflow dello stack da annidamento profondo è in gran parte storia: l'analizzatore di V8 è iterativo, e un milione di livelli di array annidati si sono analizzati senza errori su Node 26. Ciò che merita davvero di essere limitato è la dimensione e il tempo. Un analizzatore deve leggere l'intero documento prima di produrre qualcosa, quindi un corpo illimitato significa memoria illimitata, e le chiavi duplicate, i numeri smisurati e i campi inattesi vanno comunque rifiutati al confine. Limita il corpo della richiesta, poi convalida.

Articoli che potrebbero interessarti

Tutte le guide
GuidaLa formattazione SQL e la clausola IN che rompe la produzioneCostruire una lista IN per concatenazione di stringhe è insieme il classico vettore di iniezione e un dirupo prestazionale. La parametrizzazione risolve il primo strutturalmente, perché il piano è compilato prima che arrivi qualsiasi valore. Il secondo richiede aritmetica: i tetti di parametri documentati dai produttori, e cosa fa a una cache dei piani una query il cui testo cambia a ogni lunghezza di lista.SpiegazioneYAML sembra amichevole e mordeYAML è JSON più uno strato di inferenza dei tipi, ed è l'inferenza la parte pericolosa. Lo stesso file passato in un analizzatore YAML 1.2 e in uno 1.1: no è una stringa nell'uno e false nell'altro, 01234 è 1234 nell'uno e 668 nell'altro, e 12:30:00 è un numero in uno dei due.SpiegazioneDa JSON a CSV quando la struttura è annidata: perché non esiste una risposta giustaI due stessi ordini escono con cinque colonne da un convertitore e dieci da un altro, e nessuno dei due sbaglia. Percorsi con punti, array di scalari, array di oggetti e record con chiavi diverse: quattro decisioni, prese per te e quasi sempre in silenzio.SpiegazioneDa XML a JSON: attributi, ripetizione e la trappola dell'array a un solo elementoDue documenti che differiscono solo per quanti figli esistono producono due forme JSON diverse, e senza uno schema nessun convertitore può distinguerli. Più ciò che questo fa davvero con attributi, contenuto misto e spazi — e l'unica cosa che continua a non poter registrare.SpiegazioneDa CSV a JSON: i cinque casi che rompono qualsiasi convertitoreDelimitatori tra virgolette, a capo incorporati, tipi ambigui, intestazioni duplicate e codifica. Ogni caso è passato dal convertitore e qui c'è l'output esatto — compresi i due che non salva.ConfrontoJSON vs XML: qual è la differenza?JSON e XML memorizzano entrambi dati strutturati come testo, ma con compromessi diversi. Ecco come appare ciascuno, dove vince ciascuno e come scegliere.

Strumenti correlati

Fonti

Hai notato un errore in questo articolo?