Comment analyser JSON avec Node.js? Existe-t-il un module permettant de valider et d’analyser JSON de manière sécurisée?
Vous pouvez simplement utiliser JSON.parse
.
La définition de l'objet JSON
fait partie de la spécification ECMAScript 5 }. node.js est construit sur le moteur V8 de Google Chrome, qui respecte le standard ECMA. Par conséquent, node.js a également un objet global JSON
[docs] .
Remarque - JSON.parse
peut lier le thread actuel car il s'agit d'une méthode synchrone. Donc, si vous envisagez d’analyser de gros objets JSON, utilisez un analyseur JSON en continu.
vous pouvez exiger fichiers .json.
var parsedJSON = require('./file-name');
Par exemple, si vous avez un fichier config.json
dans le même répertoire que votre fichier de code source, vous utiliserez:
var config = require('./config.json');
ou (l'extension de fichier peut être omise):
var config = require('./config');
notez que require
est synchrone et ne lit le fichier qu'une seule fois , les appels suivants renvoient le résultat du cache
Notez également que vous ne devriez l'utiliser que pour les fichiers locaux sous votre contrôle absolu, car il pourrait potentiellement exécuter du code dans le fichier.
Vous pouvez utiliser JSON.parse()
.
Vous devriez pouvoir utiliser l'objet JSON
sur n'importe quelle implémentation JavaScript ECMAScript 5 compatible. Et V8 , sur lequel Node.js est construit est l’un d’eux.
Remarque: Si vous utilisez un fichier JSON pour stocker des informations sensibles (par exemple, des mots de passe), c'est une mauvaise façon de le faire. Découvrez comment Heroku le fait: https://devcenter.heroku.com/articles/config-vars#setting-up-config-vars-for-a-deployed-application . Découvrez comment votre plate-forme le fait et utilisez
process.env
pour récupérer les vars de configuration à partir du code.
var str = '{ "name": "John Doe", "age": 42 }';
var obj = JSON.parse(str);
Vous devrez effectuer certaines opérations sur les fichiers avec le module fs
.
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);
});
var fs = require('fs');
var json = JSON.parse(fs.readFileSync('/path/to/file.json', 'utf8'));
require
? Repensez-vous!Vous pouvez parfois utiliser require
:
var obj = require('path/to/file.json');
Mais, je ne le recommande pas pour plusieurs raisons:
require
est synchrone. Si vous avez un très gros fichier JSON, cela va gâcher votre boucle d'événements. Vous devez vraiment utiliser JSON.parse
avec fs.readFile
.require
lira le fichier une seule fois. Les appels ultérieurs à require
pour le même fichier renverront une copie en cache. Ce n'est pas une bonne idée si vous voulez lire un fichier .json
qui est continuellement mis à jour. Vous pouvez utiliser un hack . Mais à ce stade, il est plus facile d’utiliser simplement fs
..json
, require
ne traitera pas le contenu du fichier en tant que JSON.Sérieusement! Utilisez JSON.parse
.
load-json-file
moduleSi vous lisez un grand nombre de fichiers .json
(et si vous êtes extrêmement paresseux), il devient ennuyeux d'écrire du code passe-partout à chaque fois. Vous pouvez sauvegarder certains caractères en utilisant le module load-json-file
.
const loadJsonFile = require('load-json-file');
loadJsonFile('/path/to/file.json').then(json => {
// `json` contains the parsed object
});
let obj = loadJsonFile.sync('/path/to/file.json');
Si le contenu JSON est diffusé sur le réseau, vous devez utiliser un analyseur JSON de diffusion. Sinon, votre processeur sera bloqué et votre boucle d'évènements amortie jusqu'à ce que le contenu JSON soit entièrement diffusé.
Il y a beaucoup de paquets disponibles dans NPM pour cela. Choisissez ce qui vous convient le mieux.
Si vous ne savez pas si tout ce qui est passé à JSON.parse()
est JSON valide, veillez à inclure l'appel à JSON.parse()
dans un bloc try/catch
. Une chaîne JSON fournie par l'utilisateur pourrait planter votre application et même conduire à des failles de sécurité. Assurez-vous que le traitement des erreurs est terminé si vous analysez du JSON fourni en externe.
utilisez l'objet JSON :
JSON.parse(str);
Un autre exemple de 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);
});
Je voudrais mentionner qu’il existe des alternatives à l’objet JSON global .JSON.parse
et JSON.stringify
sont tous deux synchrones. Par conséquent, si vous souhaitez gérer des objets volumineux, vous pouvez consulter certains des modules JSON asynchrones.
Jetez un coup d'œil: https://github.com/joyent/node/wiki/Modules#wiki-parsers-json
Incluez la bibliothèque node-fs
.
var fs = require("fs");
var file = JSON.parse(fs.readFileSync("./PATH/data.json", "utf8"));
Pour plus d'informations sur la bibliothèque 'fs', consultez la documentation à http://nodejs.org/api/fs.html
Puisque vous ne savez pas que votre chaîne est réellement valide, je la mettrais d'abord dans une capture d'essai. De plus, comme les blocs catch ne sont pas optimisés par noeud, je mettrais le tout dans une autre fonction:
function tryParseJson(str) {
try {
return JSON.parse(str);
} catch (ex) {
return null;
}
}
OU en "style async"
function tryParseJson(str, callback) {
process.nextTick(function () {
try {
callback(null, JSON.parse(str));
} catch (ex) {
callback(ex)
}
})
}
Analyser un flux JSON? Utilisez 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
}))
JSON.parse("your string");
C'est tout.
comme d'autres réponses ici mentionnées, vous voudrez probablement soit exiger un fichier json local que vous savez sûr et présent, comme un fichier de configuration:
var objectFromRequire = require('path/to/my/config.json');
ou pour utiliser l'objet JSON global pour analyser une valeur de chaîne dans un objet:
var stringContainingJson = '\"json that is obtained from somewhere\"';
var objectFromParse = JSON.parse(stringContainingJson);
notez que lorsque vous avez besoin d'un fichier, son contenu est évalué, ce qui présente un risque pour la sécurité si ce n'est pas un fichier json, mais un fichier js.
ici, j'ai publié une démo où vous pouvez voir les deux méthodes et jouer avec elles en ligne (l'exemple d'analyse est dans le fichier app.js - cliquez ensuite sur le bouton de l'exécution et voyez le résultat dans le terminal): http://staging1.codefresh.io/labs/api/env/json-parse-example }
vous pouvez modifier le code et voir l'impact ...
Tout le monde ici a parlé de JSON.parse, alors j’ai pensé à dire autre chose. Il existe un excellent module Connect avec de nombreux middleware pour faciliter et améliorer le développement d'applications. L'un des middleware est bodyParser . Il analyse JSON, html-forms, etc. Il existe également un middleware spécifique pour l'analyse JSON uniquement noop .
Jetez un coup d'œil aux liens ci-dessus, cela pourrait vous être très utile.
Ma solution:
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);
});
Utilisation de JSON pour votre configuration avec Node.js? Lisez ceci et obtenez plus de 9000 compétences en configuration ...
Remarque: Les personnes qui déclarent que data = require ('./ data.json'); est un risque de sécurité et vote négatif des réponses des gens avec zèle: vous êtes exactement et complètementfaux. Essayez de placer des fichiers non-JSON dans ce fichier ... Le nœud vous donnera une erreur, exactement comme si vous faisiez la même chose avec le beaucoup plus lent et plus difficile à coder le fichier manuel. lire et ensuite JSON.parse (). S'il vous plaît, arrêtez de répandre la désinformation; vous blessez le monde sans aider. Le nœud a été conçu pour permettre cela; ce n'est pas un risque de sécurité!
Les applications appropriées se présentent sous 3+couchesde configuration:
La plupart des développeurs traitent leur configuration de serveur et d'application comme si elle pouvait changer. Ça ne peut pas. Vous pouvez modifier les couches} des couches supérieures les unes sur les autres, mais vous êtes modifier les exigences de base. Certaines choses besoin d'exister! Faites que votre configuration agisse comme si elle était immuable, car certaines d'entre elles le sont, tout comme votre code source.
Ne pas voir que bon nombre de vos fichiers ne changeront pas après le démarrage entraîne des anti-motifs tels que le chargement de votre configuration par des blocs try/catch et prétendre que vous pouvez continuer sans votre application correctement configurée. Tu ne peux pas. Si vous le pouvez, cela appartient à la couche de configuration communauté/utilisateur, pas à la couche de configuration serveur/application. Vous faites juste la mauvaise chose. Les éléments facultatifs doivent être superposés lorsque l'application termine son bootstrap.
Arrêtez de vous cogner la tête contre le mur: votre configuration devrait être ultra simple .
Jetez un coup d'œil à la facilité d'installation d'un élément aussi complexe qu'un framework de services indépendant du protocole et du source de données, utilisant un simple fichier de configuration json et un simple fichier 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 ... (le moteur qui alimente tout)
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 ... (le code qui alimente votre service indépendant du protocole et de la source de données)
module.exports = function(request, response){
response.end('Responding to: ' + request.url);
}
Grâce à ce modèle, vous pouvez désormais charger des éléments de configuration de communauté et d’utilisateur par-dessus votre application démarrée. Dev ops est prêt à transférer votre travail dans un conteneur et à le redimensionner. Vous êtes lu pour multi-locataire. Userland est isolé. Vous pouvez maintenant séparer les préoccupations du protocole de service que vous utilisez, du type de base de données que vous utilisez, et vous concentrer simplement sur l'écriture de bon code.
Parce que vous utilisez des couches, vous pouvez vous fier à une seule source de vérité pour tout, à tout moment (l’objet de configuration en couches), et éviter les vérifications d’erreur à chaque étape, en vous inquiétant de "oh merde, comment vais-je faire this fonctionne sans configuration correcte?!? ".
Je veux juste compléter la réponse (comme je l'ai lutté pendant un moment), je veux montrer comment accéder aux informations sur JSON, cet exemple montre comment accéder à 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);
}
})
Simplement pour que ce soit aussi compliqué que possible et que vous apportiez autant de paquets que possible ...
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);
Cela vous permet de faire:
var dataPromise = readJsonFile("foo.json");
dataPromise.then(console.log);
Ou si vous utilisez async/wait:
let data = await readJsonFile("foo.json");
L'avantage par rapport à l'utilisation de readFileSync
est que votre serveur de nœud peut traiter d'autres requêtes pendant la lecture du fichier sur le disque.
Veillez toujours à utiliser JSON.parse dans essayez catch block en tant que noeud émettez toujours une erreur inattendue si vous avez des données corrompues dans votre json, utilisez donc ce code au lieu du simple JSON.Parse.
try{
JSON.parse(data)
}
catch(e){
throw new Error("data is corrupted")
}
Si vous souhaitez ajouter des commentaires dans votre code JSON et autoriser les virgules de fin, vous pouvez utiliser l’application ci-dessous:
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);
}
Notez que cela pourrait ne pas fonctionner correctement si vous avez quelque chose comme "abc": "foo // bar"
dans votre JSON. Donc, YMMV.
Utilisez la fonction tentative de Lodash pour renvoyer un objet d'erreur que vous pouvez gérer avec la fonction 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
JSON.parse n'assurera pas la sécurité de la chaîne json que vous analysez. Vous devriez regarder une bibliothèque comme json-safe-parse ou une bibliothèque similaire.
De la page jpm-safe-parse npm:
JSON.parse est excellent, mais il a un défaut grave dans le contexte de JavaScript: il vous permet de remplacer les propriétés héritées. Cela peut devenir un problème si vous analysez JSON à partir d'une source non fiable (par exemple, un utilisateur) et si vous appelez des fonctions sur ce dernier, vous vous attendriez à exister.
Si le fichier source JSON est assez volumineux, vous pouvez envisager l’itinéraire asynchrone via une approche async/wait native avec Node.js 8.0 comme suit
const fs = require('fs')
const fsReadFile = (fileName) => {
fileName = `${__dirname}/${fileName}`
return new Promise((resolve, reject) => {
fs.readFile(fileName, 'utf8', (error, data) => {
if (!error && data) {
resolve(data)
} else {
reject(error);
}
});
})
}
async function parseJSON(fileName) {
try {
return JSON.parse(await fsReadFile(fileName));
} catch (err) {
return { Error: `Something has gone wrong: ${err}` };
}
}
parseJSON('veryBigFile.json')
.then(res => console.log(res))
.catch(err => console.log(err))
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.');
J'utilise fs-extra . J'aime beaucoup parce que, même s'il prend en charge les rappels, il prend également en charge Promises . Cela me permet donc d’écrire mon code de manière beaucoup plus lisible:
const fs = require('fs-extra');
fs.readJson("path/to/foo.json").then(obj => {
//Do dome stuff with obj
})
.catch(err => {
console.error(err);
});
Il a également de nombreuses méthodes utiles qui ne viennent pas avec le module fs
standard et, en plus, il relie également les méthodes du module natif fs
et les promet.
REMARQUE: vous pouvez toujours utiliser les méthodes natives Node.js. Ils sont promis et copiés sur fs-extra. Voir les notes sur
fs.read()
&fs.write()
C'est donc fondamentalement tous les avantages. J'espère que d'autres trouveront cela utile.
Utilisez JSON.parse(str);
. Lire plus il ici .
Voici quelques exemples:
var jsonStr = '{"result":true, "count":42}';
obj = JSON.parse(jsonStr);
console.log(obj.count); //expected output: 42
console.log(obj.result); // expected output: true
Comme indiqué dans les réponses ci-dessus, nous pouvons utiliser JSON.parse()
pour analyser les chaînes au format JSON. Mais avant d’analyser, veillez à analyser les données correctes, sans quoi cela pourrait compromettre l’ensemble de votre application.
il est prudent de l'utiliser comme ça
let parsedObj = {}
try {
parsedObj = JSON.parse(data);
} catch(e) {
console.log("Cannot parse because data is not is proper json format")
}
Utilisez ceci pour être du bon côté
var data = JSON.parse(Buffer.concat(arr).toString());
Vous pouvez utiliser JSON.parse () (une fonction intégrée qui va probablement vous obliger à l'envelopper avec des instructions try-catch).
Ou utilisez une bibliothèque npm d'analyse JSON, quelque chose comme json-parse-or
NodeJs est un JavaScript serveur basé, vous pouvez donc faire comme vous le faites en pure JavaScript ...
Imaginez que vous avez ceci Json in NodeJs ...
var details = '{ "name": "Alireza Dezfoolian", "netWorth": "$0" }';
var obj = JSON.parse(details);
Et vous pouvez faire plus haut pour obtenir une version analysée de votre json ...