Node.jsを使用してJSONを解析するにはどうすればよいですか?JSONを安全に検証および解析するモジュールはありますか?
Node.jsを使用してJSONを解析するにはどうすればよいですか?JSONを安全に検証および解析するモジュールはありますか?
回答:
単純に使用できますJSON.parse
。
JSON
オブジェクトの定義はECMAScript 5仕様の一部です。node.jsは、ECMA標準に準拠するGoogle ChromeのV8エンジンに基づいて構築されています。したがって、node.jsにもグローバルオブジェクト[ドキュメント]があります。JSON
注- JSON.parse
同期メソッドであるため、現在のスレッドを拘束する可能性があります。したがって、大きなJSONオブジェクトの解析を計画している場合は、ストリーミングjsonパーサーを使用してください。
.jsonファイルを要求できます。
var parsedJSON = require('./file-name');
たとえばconfig.json
、ソースコードファイルと同じディレクトリにファイルがある場合は、次のようにします。
var config = require('./config.json');
または(ファイル拡張子は省略できます):
var config = require('./config');
これrequire
は同期的で、ファイルを1回だけ読み取ることに注意してください。その後の呼び出しは、キャッシュから結果を返します。
また、これはファイル内のコードを実行する可能性があるため、絶対制御下のローカルファイルにのみ使用してください。
require
同期していることに注意してください。fs.readFile
代わりに非同期で使いたい場合JSON.parse
.json
拡張機能を使用することを忘れないでください!ファイルに拡張子がない場合.json
、requireはそれをjsonファイルとして扱いません。
使用できますJSON.parse()
。
ECMAScript 5互換のJavaScript実装でJSON
オブジェクトを使用できるはずです。そして、Node.jsが構築されているV8もその1つです。
注:JSONファイルを使用して機密情報(パスワードなど)を格納している場合、それは間違った方法です。Herokuの仕組みをご覧ください:https : //devcenter.heroku.com/articles/config-vars#setting-up-config-vars-for-a-deployed-application。プラットフォームがそれをどのように行うかを調べ、を使用
process.env
してコード内から構成変数を取得します。
var str = '{ "name": "John Doe", "age": 42 }';
var obj = JSON.parse(str);
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
?もう一度考えて!var obj = require('path/to/file.json');
しかし、これはいくつかの理由でお勧めしません。
require
同期です。非常に大きなJSONファイルがある場合、イベントループが詰まります。あなたは本当にで使用JSON.parse
する必要がありますfs.readFile
。require
ファイルは1回だけ読み込まれます。require
同じファイルを次に呼び出すと、キャッシュされたコピーが返されます。.json
継続的に更新されるファイルを読みたい場合はお勧めできません。あなたはハックを使うことができます。ただし、現時点では、を使用する方が簡単fs
です。.json
拡張子を、require
JSONなどのファイルの内容を処理しません。マジ!を使用しJSON.parse
ます。
load-json-file
モジュール多数の.json
ファイルを読み取っている場合(および非常に遅延している場合)、毎回定型コードを作成するのは面倒です。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');
JSONコンテンツがネットワーク経由でストリーミングされる場合は、ストリーミングJSONパーサーを使用する必要があります。それ以外の場合は、JSONコンテンツが完全にストリーミングされるまで、プロセッサを拘束し、イベントループを抑制します。
このためにNPMで利用可能なパッケージはたくさんあります。あなたに最適なものを選択してください。
渡されたものJSON.parse()
が有効なJSONであるかどうか不明な場合は、呼び出しを必ずブロックJSON.parse()
内で囲んでtry/catch
ください。ユーザーが提供したJSON文字列はアプリケーションをクラッシュさせる可能性があり、セキュリティホールにつながる可能性さえあります。外部から提供されたJSONを解析する場合は、エラー処理が行われていることを確認してください。
and could even lead to security holes
好奇心から、どうやって?
<script>...
に含まれていて、エラーがクライアント側に流出した場合、XSSバグがそこにあります。したがって、IMOでは、解析する場所でJSONエラーを処理することが重要です。
require
JSONを含めるために使用するのはかっこいいと思いませんか?」副作用を文書化することさえしませんでした。これは、requireがJavaScriptとJSONの2つの言語でファイルを受け入れることも意味しました(同じではありません)。SRPはこれで終わりです。
JSONオブジェクトを使用します。
JSON.parse(str);
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);
});
グローバルJSONオブジェクトの代替手段があることを述べておきます。
JSON.parse
とJSON.stringify
同期の両方であるため、大きなオブジェクトを処理する場合は、いくつかの非同期JSONモジュールをチェックアウトすることをお勧めします。
見てください:https : //github.com/joyent/node/wiki/Modules#wiki-parsers-json
JSON.parse
アプリケーション全体で解析されている場合、クラッシュするか、を使用するとprocess.on('uncaughtException', function(err) { ... });
、最終的にユーザーに「不正な形式のJSON」エラーを送信する機会がなくなります。
async
パーサーですか?見つかりませんでした。
node-fs
ライブラリを含めます。
var fs = require("fs");
var file = JSON.parse(fs.readFileSync("./PATH/data.json", "utf8"));
「fs」ライブラリの詳細については、http://nodejs.org/api/fs.htmlにあるドキュメントを参照してください。
文字列が実際に有効であることを知らないので、私はまずそれをtry catchに入れます。また、try catchブロックはノードによって最適化されていないため、すべてを別の関数に入れます。
function tryParseJson(str) {
try {
return JSON.parse(str);
} catch (ex) {
return null;
}
}
または「非同期スタイル」
function tryParseJson(str, callback) {
process.nextTick(function () {
try {
callback(null, JSON.parse(str));
} catch (ex) {
callback(ex)
}
})
}
JSONストリームを解析していますか?を使用し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について語ったので、私は何か別のことを言うことを考えました。多くのミドルウェアと接続してアプリの開発をより簡単に、より良くするための素晴らしいモジュールがあります。ミドルウェアの1つはbodyParserです。JSON、htmlフォームなどを解析します。JSONがnoopのみを解析するための特定のミドルウェアもあります。
上記のリンクをご覧ください。非常に役立つ場合があります。
JSON.parse("your string");
それで全部です。
ここでの他の回答が述べたように、おそらく構成ファイルのように、安全で存在することがわかっているローカルjsonファイルを必要とする場合があります。
var objectFromRequire = require('path/to/my/config.json');
または、グローバルJSONオブジェクトを使用して、文字列値をオブジェクトに解析します。
var stringContainingJson = '\"json that is obtained from somewhere\"';
var objectFromParse = JSON.parse(stringContainingJson);
ファイルが必要な場合は、そのファイルのコンテンツが評価されるため、jsonファイルではなくjsファイルの場合にセキュリティリスクが発生することに注意してください。
ここでは、両方の方法を確認してオンラインで試すことができるデモを公開しました(解析の例はapp.jsファイルにあります。次に、実行ボタンをクリックしてターミナルで結果を確認します): http:// staging1 .codefresh.io / labs / api / env / json-parse-example
コードを変更して影響を確認できます...
Node.jsの構成にJSONを使用していますか?これを読んで、9000以上の構成スキルを身につけてください...
注:データを要求する人々= require( './ data.json'); はセキュリティリスクであり、熱心な熱意で人々の回答に反対票を投じます。あなたは正確かつ完全に間違っています。そのファイルに非JSONを配置してみてください... Nodeは、手動ファイルの読み取りをコーディングし、その後に続くJSON.parse()をコーディングするのがはるかに遅くて難しいコードで同じことをした場合とまったく同じように、エラーを出します。誤報の拡散をやめてください。あなたは世界を傷つけているのであって、助けていないのです。ノードはこれを可能にするように設計されました。セキュリティリスクではありません!
適切なアプリケーションには、3 層以上の構成があります。
ほとんどの開発者は、サーバーとアプリの構成を変更できるかのように扱います。できません。あなたはできる変化層互いの上に上位層からの、しかし、あなたはしている基本要件を変更します。いくつか存在する必要があります!ソースコードと同じように、構成の一部は基本的に不変であるため、構成を不変に動作させます。
起動後に構成の多くが変更されないことを確認しないと、try / catchブロックで構成の読み込みを散らかし、アプリケーションを適切にセットアップしなくても続行できるふりをするなど、アンチパターンが発生します。できません。可能であれば、それはサーバー/アプリ構成層ではなく、コミュニティ/ユーザー構成層に属します。あなたはただそれを間違っているのです。オプションのものは、アプリケーションがブートストラップを終了したときに上に重ねる必要があります。
頭を壁にぶつけないでください。設定は非常にシンプルでなければなりません。
単純なjson構成ファイルと単純な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 ...(すべてを動かすエンジン)
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 ...(プロトコルに依存しないサービスとデータソースに依存しないサービスを強化するコード)
module.exports = function(request, response){
response.end('Responding to: ' + request.url);
}
このパターンを使用して、起動したアプリの上にコミュニティとユーザーの設定をロードできるようになりました。開発者は作業をコンテナに入れてスケーリングする準備ができています。あなたはマルチテナントについて読まれています。ユーザーランドは孤立しています。これで、使用しているサービスプロトコル、使用しているデータベースタイプの問題を分離し、適切なコードの作成に集中できます。
あなたがレイヤーを使用しているので、あなたはああがらくた、どのように私はするつもりです」心配を、任意の時間(層状のconfigオブジェクト)で、すべての真理の単一のソースに依存し、すべてのステップで回避エラーチェックすることができ、これを適切な設定なしで動作しますか?!?」
私の解決策:
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
エラーが発生し続けます-この問題のデバッグをどこから始めればよいですか?
答えを完成させたい(しばらくの間私はそれで苦労した)、json情報へのアクセス方法を示したい、この例はJson配列へのアクセスを示しています。
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);
}
})
これをできるだけ複雑にし、できるだけ多くのパッケージを取り込むために...
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);
これにより、次のことが可能になります。
var dataPromise = readJsonFile("foo.json");
dataPromise.then(console.log);
または、async / awaitを使用している場合:
let data = await readJsonFile("foo.json");
使用するだけの利点readFileSync
は、ファイルがディスクから読み取られている間にノードサーバーが他のリクエストを処理できることです。
JSON.parseは、解析しているjson文字列の安全性を保証しません。あなたのようなライブラリをご覧くださいJSON-安全解析または類似のライブラリ。
json-safe-parse npmページから:
JSON.parseはすばらしいですが、JavaScriptのコンテキストに重大な欠陥が1つあります。継承されたプロパティを上書きできるためです。信頼できないソース(例:ユーザー)からJSONを解析し、その上で存在すると予想される関数を呼び出す場合、これは問題になる可能性があります。
Lodashの試行関数を利用して、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
.bind
単に_.attempt(JSON.parse、str)を使用する代わりに追加した理由を説明できますか
JSONにコメントを追加し、末尾のコンマを許可する場合は、以下の実装を使用できます。
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);
}
"abc": "foo // bar"
JSONの中に何かがある場合、うまく機能しない可能性があることに注意してください。だからYMMV。
JSONソースファイルがかなり大きい場合、Node.js 8.0でのネイティブのasync / awaitアプローチによる非同期ルートを次のように検討する必要があるかもしれません
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))
私はfs-extraを使用しています。それはcallbacks-をサポート-althoughそれもサポートしているので、それのように、私はたくさんの約束を。したがって、コードをはるかに読みやすい方法で記述できるようになります。
const fs = require('fs-extra');
fs.readJson("path/to/foo.json").then(obj => {
//Do dome stuff with obj
})
.catch(err => {
console.error(err);
});
また、標準fs
モジュールに付属していない多くの便利なメソッドがあり、さらに、ネイティブfs
モジュールからのメソッドをブリッジして約束します。
注:ネイティブのNode.jsメソッドを引き続き使用できます。それらは約束され、fs-extraにコピーされます。
fs.read()
&に関するメモを参照fs.write()
つまり、それは基本的にすべての利点です。私は他の人がこれが役に立つことを願っています。
安全な方法でNode.jsを使用してJSONを解析する必要がある場合(別名:ユーザーがデータを入力できる、またはパブリックAPI)、secure-json-parseを使用することをお勧めします。
使用法はデフォルトのようですJSON.parse
が、コードは次のことから保護されます。
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
JSON.parse()を使用できます(これは、try-catchステートメントでラップするように強制する組み込み関数です)。
または、json-parse-orのようなJSON解析npmライブラリを使用してください
安全のためにこれを使用してください
var data = JSON.parse(Buffer.concat(arr).toString());
を使用しJSON.parse(str);
ます。詳しくはこちらをご覧ください。
ここではいくつかの例を示します。
var jsonStr = '{"result":true, "count":42}';
obj = JSON.parse(jsonStr);
console.log(obj.count); // expected output: 42
console.log(obj.result); // expected output: true
シンプルですJSON.stringify(json_obj)
。JSONをを使用して文字列に変換し、を使用して文字列をJSONに変換できますJSON.parse("your json string")
。