Articolo originale: JSON Stringify Example – How to Parse a JSON Object with JS di Kris Koishigawa

Tradotto e adattato da: Angelo Mirabelli

JSON, o JavaScript Object Notation, è ovunque intorno a noi. Se hai mai utilizzato una Web app, ci sono ottime possibilità che tu abbia utilizzato JSON per strutturare, archiviare e trasmettere dati tra i suoi server e il tuo dispositivo.

In questo articolo, esamineremo brevemente le differenze tra JSON e JavaScript, quindi passeremo ai diversi modi per analizzare JSON con JavaScript nel browser e nei progetti Node.js.

Differenze tra JSON e JavaScript

Sebbene JSON assomigli a un normale JavaScript, è meglio pensare a JSON come a un formato di dati, simile a un file di testo. Dato che JSON è basato sulla sintassi JavaScript, questo è il motivo per cui sembrano così simili.

Diamo un'occhiata agli oggetti JSON e agli array JSON e confrontiamoli con le loro controparti in JavaScript.

Oggetti JSON vs oggetti letterali di JavaScript

Innanzitutto, ecco un oggetto JSON:

{
  "name": "Jane Doe",
  "favorite-game": "Stardew Valley",
  "subscriber": false
}
jane-profile.json

La principale differenza tra un oggetto JSON e un normale oggetto JavaScript, chiamato anche oggetto letterale, si riduce alle virgolette. Tutte le chiavi e i valori di tipo stringa in un oggetto JSON devono essere racchiusi tra virgolette doppie (").

Gli oggetti letterali di JavaScript sono un po' più flessibili. Con gli oggetti letterali, non è necessario racchiudere chiavi e stringhe tra virgolette doppie. È invece possibile utilizzare virgolette singole (') o non utilizzare alcun tipo di virgolette per le chiavi.

Ecco come potrebbe apparire il codice sopra per un oggetto letterale in JavaScript:

const profile = {
  name: 'Jane Doe',
  'favorite-game': 'Stardew Valley',
  subscriber: false
}

Si noti che la chiave 'favorite-game' è racchiusa tra virgolette singole. Con gli oggetti letterali, dovrai racchiudere tra virgolette le chiavi in ​​cui le parole sono separate da trattini (-).

Se desideri evitare le virgolette, puoi riscrivere la chiave usando le maiuscole e minuscole ( favoriteGame) o separare le parole con un trattino basso (favorite_game).

Array JSON vs array JavaScript

Gli array JSON funzionano più o meno allo stesso modo degli array in JavaScript e possono contenere stringhe, valori booleani, numeri e altri oggetti JSON. Per esempio:

[
  {
    "name": "Jane Doe",
    "favorite-game": "Stardew Valley",
    "subscriber": false
  },
  {
    "name": "John Doe",
    "favorite-game": "Dragon Quest XI",
    "subscriber": true
  }
]
profiles.json


Ecco come potrebbe apparire in semplice JavaScript:

const profiles = [
  {
    name: 'Jane Doe',
    'favorite-game': 'Stardew Valley',
    subscriber: false
  },
  {
    name: 'John Doe',
    'favorite-game': 'Dragon Quest XI',
    subscriber: true
  }
];

JSON come stringa

Potresti chiederti, se ci sono oggetti e array JSON, non potresti usarli nel tuo programma come normali oggetti letterali JavaScript o array ?

Il motivo per cui non puoi farlo è che JSON è in realtà solo una stringa.

Ad esempio, quando scrivi JSON in un file separato come jane-profile.json o profiles.json visti prima, quel file contiene effettivamente del testo sotto forma di un oggetto o un array JSON, che sembra essere JavaScript.

E se fai una richiesta a un'API, restituirà qualcosa del genere:

{"name":"Jane Doe","favorite-game":"Stardew Valley","subscriber":false}

Proprio come con i file di testo, se desideri utilizzare JSON nel tuo progetto, dovrai analizzarlo o modificarlo in qualcosa che il tuo linguaggio di programmazione possa comprendere. Ad esempio, l'analisi di un oggetto JSON in Python creerà un dizionario.

Con questo chiarimento, diamo un'occhiata a diversi modi per analizzare JSON in JavaScript.

Come analizzare JSON nel browser

Se stai lavorando con JSON nel browser, probabilmente stai ricevendo o inviando dati tramite un'API.

Diamo un'occhiata a un paio di esempi.

Come analizzare JSON con fetch

Il modo più semplice per ottenere dati da un'API è con fetch, che include il metodo .json() per convertire automaticamente le risposte JSON in un oggetto letterale o in un array JavaScript utilizzabile .

Ecco del codice che utilizza fetch per fare una richiesta GET per una battuta a tema sviluppatore, dall'API gratuita Chuck Norris Jokes :

fetch('https://api.chucknorris.io/jokes/random?category=dev')
  .then(res => res.json()) // the .json() method parses the JSON response into a JS object literal
  .then(data => console.log(data));

Se esegui quel codice nel browser, vedrai qualcosa di simile stampato sulla console:

{
    "categories": ["dev"],
    "created_at": "2020-01-05 13:42:19.324003",
    "icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
    "id": "elgv2wkvt8ioag6xywykbq",
    "updated_at": "2020-01-05 13:42:19.324003",
    "url": "https://api.chucknorris.io/jokes/elgv2wkvt8ioag6xywykbq",
    "value": "Chuck Norris's keyboard doesn't have a Ctrl key because nothing controls Chuck Norris."
}

Anche se sembra un oggetto JSON, in realtà è un oggetto letterale JavaScript e puoi usarlo liberamente nel tuo programma.

Come convertire in stringa JSON con JSON.stringify()

Ma cosa succede se si desidera inviare dati a un'API?

Ad esempio, supponiamo che desideri inviare una barzelletta su Chuck Norris all'API Chuck Norris Jokes in modo che altre persone possano leggerla in seguito.

Per prima cosa, scriveresti la tua battuta come un oggetto letterale JS :

const newJoke = {
  categories: ['dev'],
  value: "Chuck Norris's keyboard is made up entirely of Cmd keys because Chuck Norris is always in command."
};

Quindi, poiché stai inviando dati a un'API, dovresti trasformare l'oggetto letterale newJoke in una stringa JSON.

Fortunatamente, JavaScript include un metodo super utile per fare proprio questo, JSON.stringify():

const newJoke = {
  categories: ['dev'],
  value: "Chuck Norris's keyboard is made up entirely of Cmd keys because Chuck Norris is always in command."
};

console.log(JSON.stringify(newJoke)); // {"categories":["dev"],"value":"Chuck Norris's keyboard is made up entirely of Cmd keys because Chuck Norris is always in command."}

console.log(typeof JSON.stringify(newJoke)); // string

In questo esempio stiamo convertendo un oggetto letterale in una stringa JSON, ma JSON.stringify() funziona anche con gli array.

Infine, devi solo inviare la tua battuta in formato di stringa JSON all'API con una richiesta POST.

Nota che l'API Chuck Norris Jokes in realtà non ha questa funzione. Ma se l'avesse, ecco come potrebbe essere il codice:

const newJoke = {
  categories: ['dev'],
  value: "Chuck Norris's keyboard is made up entirely of Cmd keys because Chuck Norris is always in command."
};

fetch('https://api.chucknorris.io/jokes/submit', { // fake API endpoint
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(newJoke), // trasforma l'oggetto letterale JS in una stringa JSON
})
  .then(res => res.json())
  .then(data => console.log(data))
  .catch(err => {
    console.error(err);
  });

E proprio così, hai analizzato i dati JSON in entrata con fetch e hai usato JSON.stringify() per convertire un oggetto letterale JS in una stringa JSON.

Come lavorare con i file JSON locali nel browser

Sfortunatamente, non è possibile (o consigliabile) caricare un file JSON locale nel browser.

fetch genererà un errore se si tenta di caricare un file locale. Ad esempio, supponiamo di avere un file JSON con alcune battute:

[
  {
    "categories": ["dev"],
    "created_at": "2020-01-05 13:42:19.324003",
    "icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
    "id": "elgv2wkvt8ioag6xywykbq",
    "updated_at": "2020-01-05 13:42:19.324003",
    "url": "https://api.chucknorris.io/jokes/elgv2wkvt8ioag6xywykbq",
    "value": "Chuck Norris's keyboard doesn't have a Ctrl key because nothing controls Chuck Norris."
  },
  {
    "categories": ["dev"],
    "created_at": "2020-01-05 13:42:19.324003",
    "icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
    "id": "ae-78cogr-cb6x9hluwqtw",
    "updated_at": "2020-01-05 13:42:19.324003",
    "url": "https://api.chucknorris.io/jokes/ae-78cogr-cb6x9hluwqtw",
    "value": "There is no Esc key on Chuck Norris' keyboard, because no one escapes Chuck Norris."
  }
]
jokes.json

E vuoi analizzarlo per creare un elenco di battute su una semplice pagina HTML.

Se crei una pagina con quanto segue e la apri nel tuo browser:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="viewport" content="width=device-width" />
    <title>Fetch Local JSON</title>
  </head>
  <script>
    fetch("./jokes.json", { mode: "no-cors" }) // disable CORS because path does not contain http(s)
      .then((res) => res.json())
      .then((data) => console.log(data));
  </script>
</html>
index.html

Vedrai questo nella console:

Fetch API cannot load file://<path>/jokes.json. URL scheme "file" is not supported

Per impostazione predefinita, i browser non consentono l'accesso ai file locali per motivi di sicurezza. Questa è una buona cosa e non dovresti provare ad aggirare questo comportamento.

Invece, la cosa migliore da fare è convertire il file JSON locale in JavaScript. Fortunatamente, questo è abbastanza facile poiché la sintassi JSON è così simile a JavaScript.

Tutto quello che devi fare è creare un nuovo file e dichiarare il tuo JSON come variabile:

const jokes = [
  {
    "categories": ["dev"],
    "created_at": "2020-01-05 13:42:19.324003",
    "icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
    "id": "elgv2wkvt8ioag6xywykbq",
    "updated_at": "2020-01-05 13:42:19.324003",
    "url": "https://api.chucknorris.io/jokes/elgv2wkvt8ioag6xywykbq",
    "value": "Chuck Norris's keyboard doesn't have a Ctrl key because nothing controls Chuck Norris."
  },
  {
    "categories": ["dev"],
    "created_at": "2020-01-05 13:42:19.324003",
    "icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
    "id": "ae-78cogr-cb6x9hluwqtw",
    "updated_at": "2020-01-05 13:42:19.324003",
    "url": "https://api.chucknorris.io/jokes/ae-78cogr-cb6x9hluwqtw",
    "value": "There is no Esc key on Chuck Norris' keyboard, because no one escapes Chuck Norris."
  }
]
jokes.js

E aggiungilo alla tua pagina come uno script separato:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="viewport" content="width=device-width" />
    <title>Fetch Local JSON</title>
  </head>
  <script src="jokes.js"></script>
  <script>
    console.log(jokes);
  </script>
</html>

Sarai in grado di utilizzare l'array jokes liberamente nel tuo codice.

Puoi anche usare JavaScript modules per fare la stessa cosa, ma è un po' fuori dallo scopo di questo articolo.

Ma cosa succede se desideri lavorare con file JSON locali e hai installato Node.js? Ora diamo un'occhiata a come farlo.

Come analizzare JSON in Node.js

Node.js è un runtime JavaScript che ti consente di eseguire JavaScript al di fuori del browser. Puoi leggere tutto su Node.js qui .

Sia che utilizzi Node.js per eseguire codice localmente sul tuo computer o per eseguire intere applicazioni Web su un server, è utile sapere come lavorare con JSON.

Per i seguenti esempi, utilizzeremo lo stesso file jokes.json:

[
  {
    "categories": ["dev"],
    "created_at": "2020-01-05 13:42:19.324003",
    "icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
    "id": "elgv2wkvt8ioag6xywykbq",
    "updated_at": "2020-01-05 13:42:19.324003",
    "url": "https://api.chucknorris.io/jokes/elgv2wkvt8ioag6xywykbq",
    "value": "Chuck Norris's keyboard doesn't have a Ctrl key because nothing controls Chuck Norris."
  },
  {
    "categories": ["dev"],
    "created_at": "2020-01-05 13:42:19.324003",
    "icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
    "id": "ae-78cogr-cb6x9hluwqtw",
    "updated_at": "2020-01-05 13:42:19.324003",
    "url": "https://api.chucknorris.io/jokes/ae-78cogr-cb6x9hluwqtw",
    "value": "There is no Esc key on Chuck Norris' keyboard, because no one escapes Chuck Norris."
  }
]
jokes.json

Come analizzare un file JSON con require()

Iniziamo con il metodo più semplice.

Se hai un file JSON locale, tutto ciò che devi fare è usare require() per caricarlo come qualsiasi altro modulo Node.js:

const jokes = require('./jokes.json');

Il file JSON verrà analizzato automaticamente e potrai iniziare a usarlo nel tuo progetto:

const jokes = require('./jokes.json');

console.log(jokes[0].value); // "Chuck Norris's keyboard doesn't have a Ctrl key because nothing controls Chuck Norris."

Nota che questo è sincrono, il che significa che il tuo programma si fermerà finché non analizzerà l'intero file prima di continuare. I file JSON molto grandi possono causare il rallentamento del programma, quindi fai attenzione.

Inoltre, poiché l'analisi JSON fatta in questo modo carica l'intera cosa in memoria, è meglio utilizzare questo metodo per i file JSON statici. Se il file JSON cambia mentre il programma è in esecuzione, non avrai accesso a tali modifiche finché non riavvierai il programma e analizzerai il file JSON aggiornato.

Come analizzare un file JSON con fs.readFileSync() e JSON.parse()

Questo è il modo più tradizionale (per mancanza di un termine migliore) per analizzare i file JSON nei progetti Node.js: leggere il file con il modulo fs (file system), quindi analizzare con JSON.parse().

Vediamo come farlo con il metodo fs.readFileSync(). Innanzitutto, aggiungi il modulo fs al tuo progetto:

const fs = require('fs');

Quindi, crea una nuova variabile per memorizzare l'output del file jokes.json e impostalo uguale a fs.readFileSync():

const fs = require('fs');
const jokesFile = fs.readFileSync();

fs.readFileSync() prende un paio di argomenti. Il primo è il percorso del file che vuoi leggere:

const fs = require('fs');
const jokesFile = fs.readFileSync('./jokes.json');

Ma se ora stampi jokesFile sulla console, vedresti qualcosa del genere:

<Buffer 5b 0a 20 20 7b 0a 20 20 20 20 22 63 61 74 65 67 6f 72 69 65 73 22 3a 20 5b 22 64 65 76 22 5d 2c 0a 20 20 20 20 22 63 72 65 61 74 65 64 5f 61 74 22 3a ... 788 more bytes>

Ciò significa solo che il modulo fs sta leggendo il file, ma non conosce la codifica o il formato del file. fs può essere utilizzato per caricare praticamente qualsiasi file e non solo quelli basati su testo come JSON, quindi è necessario dirgli come è codificato il file.

Per i file di testo, la codifica è solitamente utf8:

const fs = require('fs');
const jokesFile = fs.readFileSync('./jokes.json', 'utf8');

Ora se stampi jokesFile sulla console, vedrai il contenuto del file.

Ma finora stiamo solo leggendo il file, ed è ancora una stringa. Abbiamo bisogno di usare un altro metodo per trasformare jokesFile in un oggetto o un array JavaScript utilizzabile.

Per farlo, useremo JSON.parse():

const fs = require('fs');
const jokesFile = fs.readFileSync('./jokes.json', 'utf8');
const jokes = JSON.parse(jokesFile);

console.log(jokes[0].value); // "Chuck Norris's keyboard doesn't have a Ctrl key because nothing controls Chuck Norris."

Come suggerisce il nome, JSON.parse() prende una stringa JSON e la trasforma in un oggetto letterale JavaScript o array.

Come con il metodo require visto sopra, fs.readFileSync() è un metodo sincrono, il che significa che potrebbe causare un rallentamento del programma se sta leggendo un file di grandi dimensioni, JSON o altro.

Inoltre, legge il file solo una volta e lo carica in memoria. Se il file cambia, prima o poi dovrai leggerlo di nuovo. Per semplificare le cose, potresti voler creare una semplice funzione per leggere i file.

Ecco come potrebbe essere:

const fs = require('fs');
const readFile = path => fs.readFileSync(path, 'utf8');

const jokesFile1 = readFile('./jokes.json');
const jokes1 = JSON.parse(jokesFile1);

console.log(jokes1[0].value); // "Chuck Norris's keyboard doesn't have a Ctrl key because nothing controls Chuck Norris."

// il file jokes.json cambia in qualche punto

const jokesFile2 = readFile('./jokes.json');
const jokes2 = JSON.parse(jokesFile2);

console.log(jokes2[0].value); // "Chuck Norris's keyboard is made up entirely of Cmd keys because Chuck Norris is always in command."

Come analizzare JSON con fs.readFile() e JSON.parse()

Il metodo fs.readFile() è molto simile a fs.readFileSync(), tranne per il fatto che funziona in modo asincrono. Questo è ottimo se hai un file di grandi dimensioni da leggere e non vuoi che venga interrotto il resto del tuo codice.

Ecco un esempio di base:

const fs = require('fs');

fs.readFile('./jokes.json', 'utf8');

Finora questo sembra simile a quello che abbiamo fatto con fs.readFileSync(), tranne per il fatto che non lo stiamo assegnando a una variabile come jokesFile. Poiché è asincrono, qualsiasi codice successivo fs.readFile() verrà eseguito prima che abbia terminato la lettura del file.

Invece, useremo una funzione di callback e trasformeremo il JSON al suo interno:

const fs = require('fs');

fs.readFile('./jokes.json', 'utf8', (err, data) => {
  if (err) console.error(err);
  const jokes = JSON.parse(data);

  console.log(jokes[0].value);
});

console.log("Questo verrà eseguito prima!");

Che stampa quanto segue sulla console:

Questo verrà eseguito prima!
Chuck Norris's keyboard doesn't have a Ctrl key because nothing controls Chuck Norris.

Come con fs.readFileSync(), fs.readFile() carica il file in memoria, il che significa che dovrai leggere di nuovo il file se cambia.

Inoltre, anche se fs.readFile() è asincrono, alla fine carica l'intero file che sta leggendo in memoria. Se hai un file enorme, potrebbe essere meglio usare invece i flussi Node.js.

Come convertire in stringa JSON con JSON.stringify() in Node.js

Infine, se stai analizzando JSON con Node.js, ci sono buone probabilità che a un certo punto dovrai restituire JSON, magari come risposta di un'API.

Fortunatamente, funziona allo stesso modo del browser: usa semplicemente JSON.stringify() per convertire oggetti letterali o gli array di oggetti JavaScript in una stringa JSON:

const newJoke = {
  categories: ['dev'],
  value: "Chuck Norris's keyboard is made up entirely of Cmd keys because Chuck Norris is always in command."
};

console.log(JSON.stringify(newJoke)); // {"categories":["dev"],"value":"Chuck Norris's keyboard is made up entirely of Cmd keys because Chuck Norris is always in command."}

E questo è tutto! Abbiamo coperto praticamente tutto ciò che devi sapere sull'utilizzo di JSON nel browser e nei progetti Node.js.

Ora vai la fuori e analizza o converti in JSON a tuo piacimento.

Ho dimenticato qualcosa? Come analizzi JSON nei tuoi progetti? Fammi sapere su Twitter .