Wie soll ich JSON mit Node.js analysieren? Gibt es ein Modul, das JSON sicher validiert und analysiert?
Wie soll ich JSON mit Node.js analysieren? Gibt es ein Modul, das JSON sicher validiert und analysiert?
Antworten:
Sie können einfach verwenden JSON.parse
.
Die Definition des JSON
Objekts ist Teil der ECMAScript 5-Spezifikation . node.js basiert auf der V8- Engine von Google Chrome , die dem ECMA-Standard entspricht. Daher hat node.js auch ein globales Objekt [docs] .JSON
Hinweis - JSON.parse
Kann den aktuellen Thread binden, da es sich um eine synchrone Methode handelt. Wenn Sie also große JSON-Objekte analysieren möchten, verwenden Sie einen Streaming-JSON-Parser.
Sie können .json-Dateien benötigen .
var parsedJSON = require('./file-name');
Wenn Sie beispielsweise eine config.json
Datei im selben Verzeichnis wie Ihre Quellcodedatei haben, würden Sie Folgendes verwenden:
var config = require('./config.json');
oder (Dateierweiterung kann weggelassen werden):
var config = require('./config');
Beachten Sie, dass require
ist synchron und liest die Datei nur einmal , kehrt nach einer Aufforderung das Ergebnis aus dem Cache
Beachten Sie auch, dass Sie dies nur für lokale Dateien verwenden sollten, die Ihrer absoluten Kontrolle unterliegen, da möglicherweise Code in der Datei ausgeführt wird.
require
synchron ist. Wenn Sie fs.readFile
stattdessen eine freundliche Verwendung mitJSON.parse
.json
Erweiterung zu verwenden! Wenn Ihre Datei NICHT die .json
Erweiterung hat, wird sie von require nicht als JSON-Datei behandelt.
Sie können verwendenJSON.parse()
.
Sie sollten in der Lage sein, das JSON
Objekt in jeder ECMAScript 5- kompatiblen JavaScript-Implementierung zu verwenden. Und V8 , auf dem Node.js basiert, ist einer von ihnen.
Hinweis: Wenn Sie eine JSON-Datei zum Speichern vertraulicher Informationen (z. B. Kennwörter) verwenden, ist dies der falsche Weg. Sehen Sie, wie Heroku es macht: https://devcenter.heroku.com/articles/config-vars#setting-up-config-vars-for-a-deployed-application . Finden Sie heraus, wie Ihre Plattform dies tut, und
process.env
rufen Sie die Konfigurationsvariablen aus dem Code heraus ab.
var str = '{ "name": "John Doe", "age": 42 }';
var obj = JSON.parse(str);
Sie müssen einige Dateivorgänge mit dem fs
Modul ausführen .
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
? Denk nochmal!Sie können manchmal verwendenrequire
:
var obj = require('path/to/file.json');
Ich empfehle dies jedoch aus mehreren Gründen nicht:
require
ist synchron. Wenn Sie eine sehr große JSON-Datei haben, wird Ihre Ereignisschleife erstickt. Sie müssen wirklich verwenden JSON.parse
mit fs.readFile
.require
liest die Datei nur einmal . Nachfolgende Aufrufe require
derselben Datei geben eine zwischengespeicherte Kopie zurück. Keine gute Idee, wenn Sie eine .json
Datei lesen möchten, die ständig aktualisiert wird. Sie könnten einen Hack gebrauchen . Aber an diesem Punkt ist es einfacher, einfach zu verwenden fs
..json
Erweiterung hat, require
wird der Inhalt der Datei nicht als JSON behandelt.Ernsthaft! Verwenden SieJSON.parse
.
load-json-file
ModulWenn Sie eine große Anzahl von .json
Dateien lesen (und wenn Sie extrem faul sind), wird es ärgerlich, jedes Mal Boilerplate-Code zu schreiben. Sie können einige Zeichen mithilfe des load-json-file
Moduls speichern .
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');
Wenn der JSON-Inhalt über das Netzwerk gestreamt wird, müssen Sie einen Streaming-JSON-Parser verwenden. Andernfalls wird Ihr Prozessor gebunden und Ihre Ereignisschleife gedrosselt, bis der JSON-Inhalt vollständig gestreamt ist.
Dafür gibt es in NPM viele Pakete . Wählen Sie, was für Sie am besten ist.
Wenn Sie nicht sicher sind, ob das, an das übergeben JSON.parse()
wird, gültiges JSON ist , stellen Sie sicher, dass der Aufruf in JSON.parse()
einem try/catch
Block eingeschlossen ist. Eine vom Benutzer bereitgestellte JSON-Zeichenfolge kann Ihre Anwendung zum Absturz bringen und sogar zu Sicherheitslücken führen. Stellen Sie sicher, dass die Fehlerbehandlung durchgeführt wird, wenn Sie extern bereitgestelltes JSON analysieren.
and could even lead to security holes
aus Neugier, wie?
<script>...
und der Fehler auf die Clientseite übertragen wurde, liegt genau dort ein XSS-Fehler vor. Daher ist es IMO wichtig, JSON-Fehler genau dort zu behandeln, wo Sie sie analysieren.
require
JSON einzuschließen?" und machte sich nicht einmal die Mühe, die Nebenwirkungen zu dokumentieren. Dies bedeutete auch, dass require Dateien in zwei Sprachen akzeptiert: JavaScript und JSON (nein, sie sind nicht gleich). Soviel zu SRP.
Verwenden Sie das JSON-Objekt :
JSON.parse(str);
Ein weiteres Beispiel für 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);
});
Ich möchte erwähnen, dass es Alternativen zum globalen JSON-Objekt gibt.
JSON.parse
und JSON.stringify
sind beide synchron. Wenn Sie also mit großen Objekten arbeiten möchten, sollten Sie einige der asynchronen JSON-Module ausprobieren.
Schauen Sie mal rein : https://github.com/joyent/node/wiki/Modules#wiki-parsers-json
JSON.parse
Ihrer gesamten Anwendung analysiert wird, stürzt es ab oder process.on('uncaughtException', function(err) { ... });
es besteht möglicherweise keine Möglichkeit, einen "fehlerhaften JSON" -Fehler an den Benutzer zu senden.
async
Parser? Ich habe es nicht gefunden.
Schließen Sie die node-fs
Bibliothek ein.
var fs = require("fs");
var file = JSON.parse(fs.readFileSync("./PATH/data.json", "utf8"));
Weitere Informationen zur 'fs'-Bibliothek finden Sie in der Dokumentation unter http://nodejs.org/api/fs.html
Da Sie nicht wissen, dass Ihre Zeichenfolge tatsächlich gültig ist, würde ich sie zuerst in einen Try-Catch einfügen. Da try catch-Blöcke nicht vom Knoten optimiert werden, würde ich das Ganze in eine andere Funktion einfügen:
function tryParseJson(str) {
try {
return JSON.parse(str);
} catch (ex) {
return null;
}
}
ODER im "asynchronen Stil"
function tryParseJson(str, callback) {
process.nextTick(function () {
try {
callback(null, JSON.parse(str));
} catch (ex) {
callback(ex)
}
})
}
JSON-Stream analysieren? Verwenden Sie 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
}))
Jeder hier hat von JSON.parse erzählt, also dachte ich daran, etwas anderes zu sagen. Es gibt ein großartiges Modul. Verbinden Sie sich mit vielen Middleware, um die Entwicklung von Apps einfacher und besser zu machen. Eine der Middleware ist bodyParser . Es analysiert JSON, HTML-Formulare usw. Es gibt auch eine spezielle Middleware für JSON, die nur Noop analysiert .
Schauen Sie sich die obigen Links an, es könnte für Sie sehr hilfreich sein.
JSON.parse("your string");
Das ist alles.
Wie in anderen Antworten bereits erwähnt, möchten Sie wahrscheinlich entweder eine lokale JSON-Datei benötigen, von der Sie wissen, dass sie sicher und vorhanden ist, z. B. eine Konfigurationsdatei:
var objectFromRequire = require('path/to/my/config.json');
oder um das globale JSON-Objekt zu verwenden, um einen Zeichenfolgenwert in ein Objekt zu analysieren:
var stringContainingJson = '\"json that is obtained from somewhere\"';
var objectFromParse = JSON.parse(stringContainingJson);
Beachten Sie, dass, wenn Sie eine Datei benötigen, der Inhalt dieser Datei ausgewertet wird, was ein Sicherheitsrisiko darstellt, falls es sich nicht um eine JSON-Datei, sondern um eine JS-Datei handelt.
Hier habe ich eine Demo veröffentlicht, in der Sie beide Methoden sehen und online damit spielen können (das Analysebeispiel befindet sich in der Datei app.js - klicken Sie dann auf die Schaltfläche Ausführen und sehen Sie das Ergebnis im Terminal): http: // staging1 .codefresh.io / labs / api / env / json-parse-Beispiel
Sie können den Code ändern und die Auswirkungen sehen ...
Verwenden Sie JSON für Ihre Konfiguration mit Node.js? Lesen Sie dies und erwerben Sie Ihre Konfigurationsfähigkeiten über 9000 ...
Hinweis: Personen, die behaupten, dass data = require ('./ data.json'); ist ein Sicherheitsrisiko und die Abstimmung der Antworten der Menschen mit eifrigem Eifer: Sie liegen genau und völlig falsch . Versuchen Sie, Nicht-JSON in diese Datei einzufügen ... Node gibt Ihnen einen Fehler, genau wie wenn Sie dasselbe mit dem viel langsameren und schwieriger zu codierenden manuellen Lesen von Dateien und anschließendem JSON.parse () tun würden. Bitte hören Sie auf, Fehlinformationen zu verbreiten. Du tust der Welt weh und hilfst nicht. Der Knoten wurde entwickelt , um dies zu ermöglichen. Es ist kein Sicherheitsrisiko!
Proper - Anwendungen kommen in 3 + Schichten der Konfiguration:
Die meisten Entwickler behandeln ihre Server- und App-Konfiguration so, als ob sie sich ändern könnte. Es kann nicht. Sie können Änderungen von höheren Ebenen übereinander legen, aber Sie ändern die Basisanforderungen . Einige Dinge müssen existieren! Stellen Sie sicher, dass Ihre Konfiguration unveränderlich ist, da ein Teil davon im Grunde genau wie Ihr Quellcode ist.
Wenn Sie nicht sehen, dass sich viele Ihrer Inhalte nach dem Start nicht ändern, führt dies zu Anti-Patterns wie dem Verunreinigen Ihrer Konfiguration mit Try / Catch-Blöcken und dem Vorgeben, dass Sie ohne Ihre ordnungsgemäß eingerichtete Anwendung fortfahren können. Das kannst du nicht. Wenn Sie können, gehört dies zur Community- / Benutzerkonfigurationsebene und nicht zur Server- / App-Konfigurationsebene. Du machst es einfach falsch. Das optionale Material sollte überlagert werden, wenn die Anwendung den Bootstrap beendet hat.
Hör auf, deinen Kopf gegen die Wand zu schlagen: Deine Konfiguration sollte extrem einfach sein .
Sehen Sie sich an, wie einfach es ist, mit einer einfachen json-Konfigurationsdatei und einer einfachen app.js-Datei etwas so Komplexes wie ein protokollunabhängiges und datenquellenunabhängiges Service-Framework einzurichten ...
container-config.js ...
{
"service": {
"type" : "http",
"name" : "login",
"port" : 8085
},
"data": {
"type" : "mysql",
"host" : "localhost",
"user" : "notRoot",
"pass" : "oober1337",
"name" : "connect"
}
}
index.js ... (die Engine, die alles antreibt )
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 ... (der Code, der Ihren protokollunabhängigen und datenquellenunabhängigen Dienst unterstützt)
module.exports = function(request, response){
response.end('Responding to: ' + request.url);
}
Mit diesem Muster können Sie jetzt Community- und Benutzerkonfigurationsdaten auf Ihre gebootete App laden. Dev ops ist bereit, Ihre Arbeit in einen Container zu schieben und zu skalieren. Sie sind für Multitenant gelesen. Userland ist isoliert. Sie können jetzt die Bedenken hinsichtlich des von Ihnen verwendeten Dienstprotokolls, des von Ihnen verwendeten Datenbanktyps trennen und sich nur darauf konzentrieren, guten Code zu schreiben.
Weil Sie Schichten verwenden, können Sie auf einer einzigen Quelle der Wahrheit vertrauen für alles, jederzeit (das geschichtete Config - Objekt), und vermeiden Sie Fehlerprüfungen bei jedem Schritt, sich Gedanken über „oh Mist, wie werde ich machen diese ohne richtige Konfiguration arbeiten?!? ".
Meine Lösung:
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);
});
TypeError: path must be a string or Buffer
Fehler angezeigt. Haben Sie eine Idee, wo Sie mit dem Debuggen dieses Problems beginnen sollen?
Ich möchte nur die Antwort vervollständigen (da ich eine Weile damit zu kämpfen hatte), möchte zeigen, wie man auf die JSON-Informationen zugreift. Dieses Beispiel zeigt den Zugriff auf das 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);
}
})
Nur um dies so kompliziert wie möglich zu gestalten und so viele Pakete wie möglich einzubringen ...
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);
So können Sie:
var dataPromise = readJsonFile("foo.json");
dataPromise.then(console.log);
Oder wenn Sie async / await verwenden:
let data = await readJsonFile("foo.json");
Der Vorteil gegenüber der bloßen Verwendung readFileSync
besteht darin, dass Ihr Knotenserver andere Anforderungen verarbeiten kann, während die Datei von der Festplatte gelesen wird.
JSON.parse gewährleistet nicht die Sicherheit der von Ihnen analysierten JSON-Zeichenfolge. Sie sollten sich eine Bibliothek wie json-safe-parse oder eine ähnliche Bibliothek ansehen .
Von der json-safe-parse npm-Seite:
JSON.parse ist großartig, hat jedoch einen schwerwiegenden Fehler im Kontext von JavaScript: Sie können geerbte Eigenschaften überschreiben. Dies kann zu einem Problem werden, wenn Sie JSON von einer nicht vertrauenswürdigen Quelle (z. B. einem Benutzer) analysieren und Funktionen aufrufen, von denen Sie erwarten würden, dass sie existieren.
Nutzen Sie die Versuchsfunktion von Lodash, um ein Fehlerobjekt zurückzugeben, das Sie mit der Funktion isError verarbeiten können.
// 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
.bind
anstatt nur _.attempt (JSON.parse, str) zu verwenden
Stellen Sie immer sicher, dass Sie JSON.parse im try catch- Block verwenden, da der Knoten immer einen unerwarteten Fehler auslöst, wenn Ihr json beschädigte Daten enthält. Verwenden Sie daher diesen Code anstelle von einfachem JSON.Parse
try{
JSON.parse(data)
}
catch(e){
throw new Error("data is corrupted")
}
Wenn Sie Ihrem JSON einige Kommentare hinzufügen und nachfolgende Kommas zulassen möchten, sollten Sie die folgende Implementierung verwenden:
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);
}
Beachten Sie, dass es möglicherweise nicht gut funktioniert, wenn Sie etwas wie "abc": "foo // bar"
in Ihrem JSON haben. Also YMMV.
Wenn die JSON-Quelldatei ziemlich groß ist, sollten Sie die asynchrone Route über den nativen asynchronen / wartenden Ansatz mit Node.js 8.0 wie folgt berücksichtigen
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))
Ich benutze fs-extra . Ich mag es sehr, weil es - obwohl es Rückrufe unterstützt - auch Versprechen unterstützt . So kann ich meinen Code viel besser lesbar schreiben:
const fs = require('fs-extra');
fs.readJson("path/to/foo.json").then(obj => {
//Do dome stuff with obj
})
.catch(err => {
console.error(err);
});
Es hat auch viele nützliche Methoden , die mit dem Standard nicht mitzukommen fs
Modul und auf Hinzu kommt , dass es auch die Methoden aus dem nativen Brücken - fs
Modul und promisifies sie.
HINWEIS: Sie können weiterhin die nativen Node.js-Methoden verwenden. Sie werden versprochen und in fs-extra kopiert. Siehe Hinweise zu
fs.read()
&fs.write()
Es sind also im Grunde alle Vorteile. Ich hoffe, andere finden das nützlich.
Wenn Sie JSON mit Node.js auf sichere Weise analysieren müssen (auch bekannt als: Der Benutzer kann Daten oder eine öffentliche API eingeben), würde ich die Verwendung von Secure-JSON-Parse empfehlen .
Die Verwendung entspricht der Standardeinstellung JSON.parse
, schützt Ihren Code jedoch vor:
const badJson = '{ "a": 5, "b": 6, "__proto__": { "x": 7 }, "constructor": {"prototype": {"bar": "baz"} } }'
const infected = JSON.parse(badJson)
console.log(infected.x) // print undefined
const x = Object.assign({}, infected)
console.log(x.x) // print 7
const sjson = require('secure-json-parse')
console.log(sjson.parse(badJson)) // it will throw by default, you can ignore malicious data also
Sie können JSON.parse () verwenden (eine integrierte Funktion, die Sie wahrscheinlich dazu zwingen wird, sie mit try-catch-Anweisungen zu versehen).
Oder verwenden Sie eine JSON-Parsing-npm-Bibliothek, z. B. json-parse-or
Verwenden Sie dies, um auf der sicheren Seite zu sein
var data = JSON.parse(Buffer.concat(arr).toString());
NodeJs ist ein JavaScript- basierter Server. Sie können dies also in reinem JavaScript tun ...
Stellen Sie sich vor, Sie haben diesen Json in NodeJs ...
var details = '{ "name": "Alireza Dezfoolian", "netWorth": "$0" }';
var obj = JSON.parse(details);
Und Sie können oben tun, um eine analysierte Version Ihres json zu erhalten ...
Wie in den obigen Antworten erwähnt, können wir JSON.parse()
die Zeichenfolgen in JSON analysieren. Stellen Sie jedoch vor dem Parsen sicher, dass Sie die richtigen Daten analysieren, da sonst Ihre gesamte Anwendung heruntergefahren werden kann
es ist sicher, es so zu benutzen
let parsedObj = {}
try {
parsedObj = JSON.parse(data);
} catch(e) {
console.log("Cannot parse because data is not is proper json format")
}
Verwenden Sie JSON.parse(str);
. Lesen Sie hier mehr darüber .
Hier sind einige Beispiele:
var jsonStr = '{"result":true, "count":42}';
obj = JSON.parse(jsonStr);
console.log(obj.count); // expected output: 42
console.log(obj.result); // expected output: true
Es ist ganz einfach: Sie können JSON mithilfe von Zeichenfolgen in Zeichenfolgen konvertieren und Zeichenfolgen mithilfe JSON.stringify(json_obj)
von JSON konvertieren JSON.parse("your json string")
.