Come analizzare JSON utilizzando Node.js?

Come devo analizzare JSON usando Node.js? C’è qualche modulo che convalida e analizza JSON in modo sicuro?

Puoi semplicemente usare JSON.parse .

node.js è basato su V8 , che fornisce l’object globale JSON [docs] . La definizione dell’object JSON fa parte delle specifiche ECMAScript 5 .

Nota: JSON.parse può bind il thread corrente perché è un metodo sincrono. Quindi, se stai pianificando di analizzare grandi oggetti JSON, usa un parser di streaming json.

puoi richiedere i file .json.

 var parsedJSON = require('./file-name'); 

Ad esempio se hai un file config.json nella stessa directory del file del codice sorgente che config.json :

 var config = require('./config.json'); 

oppure (l’estensione del file può essere omessa):

 var config = require('./config'); 

si noti che la require è sincrona e legge il file una volta sola , le chiamate successive restituiscono il risultato dalla cache

Nota inoltre Dovresti usare questo solo per i file locali sotto il tuo controllo assoluto, poiché potenzialmente esegue qualsiasi codice all’interno del file.

Puoi usare JSON.parse() .

Dovresti essere in grado di utilizzare l’object JSON su qualsiasi implementazione JavaScript compatibile con ECMAScript 5 . E V8 , su cui è costruito Node.js, è uno di questi.


Analisi di una stringa contenente dati JSON

 var str = '{ "name": "John Doe", "age": 42 }'; var obj = JSON.parse(str); 

Analisi di un file contenente dati JSON

Dovrai fare alcune operazioni sui file con il modulo fs .

Versione asincrona

 var fs = require('fs'); fs.readFile('/path/to/file.json', 'utf8', function (err, data) { if (err) throw err; // we'll not consider error handling for now var obj = JSON.parse(data); }); 

Versione sincrona

 var fs = require('fs'); var json = JSON.parse(fs.readFileSync('/path/to/file.json', 'utf8')); 

Vuoi usare require ? Pensa di nuovo!

A volte puoi usare require :

 var obj = require('path/to/file.json'); 

Ma, non lo consiglio per diversi motivi:

Nota: se si sta utilizzando un file JSON per memorizzare informazioni sensibili (ad es. Password), questo è il modo sbagliato di farlo. Guarda come lo fa Heroku: https://devcenter.heroku.com/articles/config-vars#setting-up-config-vars-for-a-deployed-application . Scopri come funziona la tua piattaforma e usa process.env per recuperare le vass di configurazione dall’interno del codice.

  1. require è sincrono. Se si dispone di un file JSON molto grande, esso soffocherà il ciclo degli eventi. Devi davvero usare JSON.parse con fs.readFile .
  2. require leggerà il file solo una volta . Le chiamate successive per require lo stesso file restituiranno una copia memorizzata nella cache. Non è una buona idea se vuoi leggere un file .json che viene continuamente aggiornato. Potresti usare un trucco . Ma a questo punto, è più facile usare semplicemente fs .
  3. Se il tuo file non ha estensione .json , require non tratterà il contenuto del file come JSON.

Sul serio! Usa JSON.parse .


modulo load-json-file

Se stai leggendo un gran numero di file .json , (e se sei estremamente pigro), diventa sempre fastidioso scrivere codice boilerplate ogni volta. Puoi salvare alcuni caratteri usando il modulo load-json-file .

 const loadJsonFile = require('load-json-file'); 

Versione asincrona

 loadJsonFile('/path/to/file.json').then(json => { // `json` contains the parsed object }); 

Versione sincrona

 let obj = loadJsonFile.sync('/path/to/file.json'); 

Parsing JSON dai flussi

Se il contenuto JSON viene trasmesso in streaming sulla rete, è necessario utilizzare un parser JSON in streaming. Altrimenti legherà il processore e soffocherà il ciclo degli eventi finché il contenuto JSON non sarà completamente trasmesso.

Ci sono molti pacchetti disponibili in NPM per questo. Scegli cosa è meglio per te.


Gestione degli errori / Sicurezza

Se non sei sicuro se tutto ciò che viene passato a JSON.parse() è JSON valido , assicurati di includere la chiamata a JSON.parse() all’interno di un blocco try/catch . Una stringa JSON fornita dall’utente potrebbe causare il blocco della tua applicazione e persino creare problemi di sicurezza. Assicurarsi che la gestione degli errori sia eseguita se si analizza JSON fornito esternamente.

usa l’ object JSON :

 JSON.parse(str); 

Un altro esempio di JSON.parse:

 var fs = require('fs'); var file = __dirname + '/config.json'; fs.readFile(file, 'utf8', function (err, data) { if (err) { console.log('Error: ' + err); return; } data = JSON.parse(data); console.dir(data); }); 

Vorrei dire che ci sono alternative all’object JSON globale. JSON.parse e JSON.stringify sono entrambi sincroni, quindi se vuoi gestire grandi oggetti potresti voler controllare alcuni dei moduli JSON asincroni.

Dai un’occhiata: https://github.com/joyent/node/wiki/Modules#wiki-parsers-json

Include la libreria node-fs .

 var fs = require("fs"); var file = JSON.parse(fs.readFileSync("./PATH/data.json", "utf8")); 

Per maggiori informazioni sulla libreria ‘fs’, consultare la documentazione su http://nodejs.org/api/fs.html

Dal momento che non sai che la tua stringa è effettivamente valida, la metterei prima in una presa try. Inoltre, poiché i blocchi di cattura non sono ottimizzati dal nodo, inserisco l’intera cosa in un’altra funzione:

 function tryParseJson(str) { try { return JSON.parse(str); } catch (ex) { return null; } } 

O in “stile asincrono”

 function tryParseJson(str, callback) { process.nextTick(function () { try { callback(null, JSON.parse(str)); } catch (ex) { callback(ex) } }) } 

Analizzare un stream JSON? Usa JSONStream .

 var request = require('request') , JSONStream = require('JSONStream') request({url: 'http://isaacs.couchone.com/registry/_all_docs'}) .pipe(JSONStream.parse('rows.*')) .pipe(es.mapSync(function (data) { return data })) 

https://github.com/dominictarr/JSONStream

 JSON.parse("your string"); 

È tutto.

come hanno già detto altre risposte, probabilmente vorrai richiedere un file json locale che sai essere sicuro e presente, come un file di configurazione:

 var objectFromRequire = require('path/to/my/config.json'); 

oppure per utilizzare l’object JSON globale per analizzare un valore stringa in un object:

 var stringContainingJson = '\"json that is obtained from somewhere\"'; var objectFromParse = JSON.parse(stringContainingJson); 

si noti che quando si richiede un file viene valutato il contenuto di quel file, che introduce un rischio per la sicurezza nel caso in cui non si tratti di un file json ma di un file js.

qui, ho pubblicato una demo in cui è ansible visualizzare entrambi i metodi e giocare con loro online (l’esempio di parsing è nel file app.js – quindi fare clic sul pulsante Esegui e vedere il risultato nel terminale): http: // staging1 .codefresh.io / laboratori / api / ENV / jSON-parse-example

puoi modificare il codice e vedere l’impatto …

Tutti qui hanno parlato di JSON.parse, quindi ho pensato di dire qualcos’altro. C’è un ottimo modulo Connettiti con molti middleware per rendere lo sviluppo di app più facile e migliore. Uno dei middleware è bodyParser . Analizza JSON, html-forms ed ecc. C’è anche un middleware specifico per JSON che analizza solo noop .

Dai uno sguardo ai link qui sopra, potrebbe esserti molto utile.

La mia soluzione:

 var fs = require('fs'); var file = __dirname + '/config.json'; fs.readFile(file, 'utf8', function (err, data) { if (err) { console.log('Error: ' + err); return; } data = JSON.parse(data); console.dir(data); }); 

Voglio solo completare la risposta (come ho faticato con esso per un po ‘), voglio mostrare come accedere alle informazioni JSON, questo esempio mostra l’accesso a JSON Array:

 var request = require('request'); request('https://server/run?oper=get_groups_joined_by_user_id&user_id=5111298845048832', function (error, response, body) { if (!error && response.statusCode == 200) { var jsonArr = JSON.parse(body); console.log(jsonArr); console.log("group id:" + jsonArr[0].id); } }) 

Usando JSON per la tua configurazione con Node.js? Leggi questo e ottieni le tue capacità di configurazione oltre 9000 …

Nota: le persone sostengono che data = require (‘./ data.json’); è un rischio per la sicurezza e downvoting le risposte delle persone con zelo zelante: sei esattamente e completamente sbagliato . Prova a inserire non-JSON in quel file … Il nodo ti darà un errore, esattamente come farebbe se avessi fatto la stessa cosa con il molto più lento e difficile da leggere la lettura manuale dei file e poi il successivo JSON.parse (). Si prega di smettere di diffondere disinformazione; stai facendo del male al mondo, non aiutando. Il nodo è stato progettato per consentire questo; non è un rischio per la sicurezza!

Le applicazioni corrette sono disponibili in 3 o più livelli di configurazione:

  1. Configurazione server / contenitore
  2. Configurazione dell’applicazione
  3. (facoltativo) Configurazione inquilino / comunità / organizzazione
  4. Configurazione utente

La maggior parte degli sviluppatori tratta il proprio server e la configurazione dell’app come se potesse cambiare. Non può Puoi sovrapporre le modifiche da livelli superiori uno sopra l’altro, ma stai modificando i requisiti di base . Alcune cose devono esistere! Fai in modo che la tua configurazione sia immutabile, perché in parte lo è, proprio come il tuo codice sorgente.

Non vedendo che molte delle tue cose non cambieranno dopo l’avvio porta a anti-pattern come sporcare la tua configurazione caricando con i blocchi try / catch e facendo finta di poter continuare senza l’applicazione di installazione corretta. Non puoi Se è ansible, ciò appartiene al livello di configurazione della comunità / utente, non al livello di configurazione del server / app. Stai solo sbagliando. Le cose facoltative dovrebbero essere sovrapposte quando l’applicazione termina il suo bootstrap.

Smettila di sbattere la testa contro il muro: la tua configurazione dovrebbe essere ultra semplice .

Date un’occhiata a quanto sia facile impostare qualcosa di così complesso come un protocollo indipendente dal protocollo e dall’agente fonte dati, utilizzando un semplice file di configurazione json e un semplice file app.js …

container-config.js …

 { "service": { "type" : "http", "name" : "login", "port" : 8085 }, "data": { "type" : "mysql", "host" : "localhost", "user" : "notRoot", "pass" : "oober1337", "name" : "connect" } } 

index.js … (il motore che alimenta tutto)

 var config = require('./container-config.json'); // Get our service configuration. var data = require(config.data.type); // Load our data source plugin ('npm install mysql' for mysql). var service = require(config.service.type); // Load our service plugin ('http' is built-in to node). var processor = require('./app.js'); // Load our processor (the code you write). var connection = data.createConnection({ host: config.data.host, user: config.data.user, password: config.data.pass, database: config.data.name }); var server = service.createServer(processor); connection.connect(); server.listen(config.service.port, function() { console.log("%s service listening on port %s", config.service.type, config.service.port); }); 

app.js … (il codice che alimenta il servizio agnostico indipendente dal protocollo e dalla fonte di dati)

 module.exports = function(request, response){ response.end('Responding to: ' + request.url); } 

Usando questo modello, ora puoi caricare le cose di configurazione della comunità e degli utenti sopra l’app di avvio, dev ops è pronto a spingere il tuo lavoro in un contenitore e ridimensionarlo. Sei letto per il multi-tenant. Userland è isolato. Ora puoi separare le preoccupazioni su quale protocollo di servizio stai usando, quale tipo di database stai usando e concentrarti solo sulla scrittura di un buon codice.

Poiché utilizzi i livelli, puoi fare affidamento su un’unica fonte di verità per tutto, in qualsiasi momento (l’object di configurazione a livelli) ed evitare i controlli di errore ad ogni passaggio, preoccupandoti di “oh merda, come farò a fare questo? funziona senza una configurazione corretta?!? “.

Solo per renderlo il più complicato ansible e portare il maggior numero ansible di pacchetti …

 const fs = require('fs'); const bluebird = require('bluebird'); const _ = require('lodash'); const readTextFile = _.partial(bluebird.promisify(fs.readFile), _, {encoding:'utf8',flag:'r'}); const readJsonFile = filename => readTextFile(filename).then(JSON.parse); 

Questo ti permette di fare:

 var dataPromise = readJsonFile("foo.json"); dataPromise.then(console.log); 

Oppure se stai usando async / attendi:

 let data = await readJsonFile("foo.json"); 

Il vantaggio rispetto all’uso di readFileSync è che il server del nodo può elaborare altre richieste mentre il file viene letto dal disco.

Se desideri aggiungere alcuni commenti nel tuo JSON e consentire le virgole finali che potresti voler utilizzare sotto l’implementazione:

 var fs = require('fs'); var data = parseJsData('./message.json'); console.log('[INFO] data:', data); function parseJsData(filename) { var json = fs.readFileSync(filename, 'utf8') .replace(/\s*\/\/.+/g, '') .replace(/,(\s*\})/g, '}') ; return JSON.parse(json); } 

Nota che potrebbe non funzionare bene se hai qualcosa come "abc": "foo // bar" nel tuo JSON. Quindi YMMV.

JSON.parse non garantisce la sicurezza della stringa json che stai analizzando. Dovresti guardare una libreria come json-safe-parse o una libreria simile.

Dalla pagina npm di json-safe-parse:

JSON.parse è ottimo, ma ha un difetto grave nel contesto di JavaScript: consente di ignorare le proprietà ereditate. Questo può diventare un problema se si analizza JSON da una fonte non attendibile (ad esempio: un utente) e si chiamano funzioni che ci si aspetterebbe che esistano.

Sfrutta la funzione di tentativo di Lodash per restituire un object errore, che puoi gestire con la funzione isError.

 // Returns an error object on failure function parseJSON(jsonString) { return _.attempt(JSON.parse.bind(null, jsonString)); } // Example Usage var goodJson = '{"id":123}'; var badJson = '{id:123}'; var goodResult = parseJSON(goodJson); var badResult = parseJSON(badJson); if (_.isError(goodResult)) { console.log('goodResult: handle error'); } else { console.log('goodResult: continue processing'); } // > goodResult: continue processing if (_.isError(badResult)) { console.log('badResult: handle error'); } else { console.log('badResult: continue processing'); } // > badResult: handle error 

Assicurati sempre di usare JSON.parse nel try catch block poiché il nodo genera sempre un errore imprevisto se hai qualche dato corrotto nel tuo json, quindi usa questo codice invece del semplice JSON.Parse

 try{ JSON.parse(data) } catch(e){ throw new Error("data is corrupted") } 
 var array={ Action: 'Login', ErrorCode: 3, Detail: 'Your account not found.' }; var http=require('http'), PORT=8789, server=function(req,res){ res.writeHead(200,{'Content-Type':'application/json'}); // JSON res.end(JSON.stringify(array)); } http.createServer(server).listen(PORT); console.log('Server started.'); 

Questo doveva essere gridato a me: funziona solo per i file .json .

Se la fine del file è diversa, questo non funziona!

Puoi usare JSON.parse () (che è una funzione incorporata che probabilmente ti costringerà a racchiuderlo con le istruzioni try-catch).

Oppure usa qualche libreria npm di analisi JSON, qualcosa come json-parse-o

Usalo per essere al sicuro

var data = JSON.parse (Buffer.concat (arr) .toString ());

Usa JSON.parse (str);

saperne di più – JSON.parse ()

esempio –

 var jsonStr = '{"result":true, "count":42}'; obj = JSON.parse(jsonStr); console.log(obj.count); //expected output: 42 console.log(obj.result); // expected output: true 

Non è necessario alcun modulo aggiuntivo.
Basta usare
var parsedObj = JSON.parse(yourObj);
Non credo ci siano problemi di sicurezza in merito

È semplice, puoi convertire JSON in string usando JSON.stringify(json_obj) e convertire string in JSON usando JSON.parse("your json string") .

 var fs = require('fs'); fs.readFile('ashish.json',{encoding:'utf8'},function(data,err) { if(err) throw err; else { console.log(data.toString()); } })