Bagaimana saya harus mengurai JSON menggunakan Node.js? Apakah ada beberapa modul yang akan memvalidasi dan mem-parsing JSON dengan aman?
Bagaimana saya harus mengurai JSON menggunakan Node.js? Apakah ada beberapa modul yang akan memvalidasi dan mem-parsing JSON dengan aman?
Jawaban:
Anda cukup menggunakan JSON.parse
.
Definisi JSON
objek adalah bagian dari spesifikasi ECMAScript 5 . node.js dibangun di mesin V8 Google Chrome , yang mematuhi standar ECMA. Oleh karena itu, node.js juga memiliki objek global [docs] .JSON
Catatan - JSON.parse
dapat mengikat utas saat ini karena ini adalah metode sinkron. Jadi jika Anda berencana untuk mem-parsing objek JSON besar gunakan streaming json parser.
Anda dapat meminta file .json.
var parsedJSON = require('./file-name');
Sebagai contoh jika Anda memiliki config.json
file dalam direktori yang sama dengan file kode sumber Anda, Anda akan menggunakan:
var config = require('./config.json');
atau (ekstensi file dapat dihilangkan):
var config = require('./config');
Catatan bahwa require
ini sinkron dan hanya membaca file sekali , panggilan berikut mengembalikan hasil dari cache
Perhatikan juga Anda hanya boleh menggunakan ini untuk file lokal di bawah kendali absolut Anda, karena berpotensi mengeksekusi kode apa pun di dalam file.
require
itu sinkron. Jika Anda ingin menggunakan ramah async fs.readFile
sebagai gantinya denganJSON.parse
.json
ekstensi! Jika file Anda TIDAK memiliki .json
ekstensi, mengharuskan tidak akan memperlakukannya sebagai file json.
Anda bisa menggunakannyaJSON.parse()
.
Anda harus dapat menggunakan JSON
objek pada implementasi JavaScript yang kompatibel dengan ECMAScript 5 . Dan V8 , di mana Node.js dibangun adalah salah satunya.
Catatan: Jika Anda menggunakan file JSON untuk menyimpan informasi sensitif (mis. Kata sandi), itu cara yang salah untuk melakukannya. Lihat bagaimana Heroku melakukannya: https://devcenter.heroku.com/articles/config-vars#setting-up-config-vars-for-a-deployed-application . Cari tahu bagaimana platform Anda melakukannya, dan gunakan
process.env
untuk mengambil konfigurasi konfigurasi dari dalam kode.
var str = '{ "name": "John Doe", "age": 42 }';
var obj = JSON.parse(str);
Anda harus melakukan beberapa operasi file dengan fs
modul.
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
? Pikirkan lagi!Anda terkadang dapat menggunakanrequire
:
var obj = require('path/to/file.json');
Tapi, saya tidak merekomendasikan ini karena beberapa alasan:
require
sinkron. Jika Anda memiliki file JSON yang sangat besar, itu akan mencekik loop acara Anda. Anda benar-benar perlu menggunakan JSON.parse
dengan fs.readFile
.require
akan membaca file hanya sekali . Panggilan selanjutnya ke require
file yang sama akan mengembalikan salinan yang di-cache. Bukan ide yang baik jika Anda ingin membaca .json
file yang terus diperbarui. Anda bisa menggunakan retasan . Tetapi pada titik ini, lebih mudah digunakan fs
..json
ekstensi, require
tidak akan memperlakukan konten file sebagai JSON.Serius! GunakanJSON.parse
.
load-json-file
modulJika Anda membaca banyak .json
file, (dan jika Anda sangat malas), akan sangat mengganggu untuk menulis kode boilerplate setiap saat. Anda dapat menyimpan beberapa karakter dengan menggunakan load-json-file
modul.
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');
Jika konten JSON dialirkan melalui jaringan, Anda perlu menggunakan pengurai JSON streaming. Kalau tidak, itu akan mengikat prosesor Anda dan mencekik acara Anda sampai konten JSON sepenuhnya dialirkan.
Ada banyak paket yang tersedia di NPM untuk ini. Pilih yang terbaik untuk Anda.
Jika Anda tidak yakin jika apa pun yang dilewatkan ke JSON.parse()
adalah JSON valid , pastikan untuk menyertakan panggilan untuk JSON.parse()
di dalam try/catch
blok. Pengguna yang menyediakan string JSON dapat merusak aplikasi Anda, dan bahkan dapat menyebabkan lubang keamanan. Pastikan penanganan kesalahan dilakukan jika Anda menguraikan JSON yang disediakan secara eksternal.
and could even lead to security holes
karena penasaran, bagaimana?
<script>...
, dan kesalahan tersebut tumpah ke sisi klien, Anda memiliki bug XSS di sana. Oleh karena itu IMO penting untuk menangani kesalahan JSON tepat di mana Anda menguraikannya.
require
untuk memasukkan JSON?" dan bahkan tidak repot-repot mendokumentasikan efek sampingnya. Ini juga berarti bahwa memerlukan menerima file dalam dua bahasa: JavaScript, dan JSON (tidak, mereka tidak sama). Begitu banyak untuk SRP.
gunakan objek JSON :
JSON.parse(str);
Contoh lain dari 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);
});
Saya ingin menyebutkan bahwa ada alternatif untuk objek JSON global.
JSON.parse
dan JSON.stringify
keduanya sinkron, jadi jika Anda ingin berurusan dengan objek besar Anda mungkin ingin memeriksa beberapa modul JSON asinkron.
Lihat: https://github.com/joyent/node/wiki/Modules#wiki-parsers-json
JSON.parse
seluruh aplikasi Anda akan mogok atau, menggunakan process.on('uncaughtException', function(err) { ... });
, pada akhirnya tidak akan ada kesempatan untuk mengirim kesalahan "malformasi JSON" kepada pengguna.
async
parser? Saya tidak menemukannya.
Sertakan node-fs
perpustakaan.
var fs = require("fs");
var file = JSON.parse(fs.readFileSync("./PATH/data.json", "utf8"));
Untuk info lebih lanjut tentang perpustakaan 'fs', lihat dokumentasi di http://nodejs.org/api/fs.html
Karena Anda tidak tahu bahwa string Anda benar-benar valid, saya akan memasukkannya terlebih dahulu ke dalam try catch. Juga karena blok coba tangkap tidak dioptimalkan oleh node, saya akan meletakkan semuanya ke fungsi lain:
function tryParseJson(str) {
try {
return JSON.parse(str);
} catch (ex) {
return null;
}
}
ATAU dalam "gaya async"
function tryParseJson(str, callback) {
process.nextTick(function () {
try {
callback(null, JSON.parse(str));
} catch (ex) {
callback(ex)
}
})
}
Parsing aliran JSON? Gunakan 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
}))
Semua orang di sini telah memberi tahu tentang JSON.parse, jadi saya berpikir untuk mengatakan sesuatu yang lain. Ada modul Connect hebat dengan banyak middleware untuk membuat pengembangan aplikasi lebih mudah dan lebih baik. Salah satu middleware adalah bodyParser . Ini mem-parsing JSON, html-bentuk dan lain-lain. Ada juga middleware khusus untuk parsing JSON hanya noop .
Lihatlah tautan di atas, mungkin ini sangat membantu Anda.
JSON.parse("your string");
Itu saja.
seperti jawaban lain yang disebutkan di sini, Anda mungkin perlu meminta file json lokal yang Anda tahu aman dan ada, seperti file konfigurasi:
var objectFromRequire = require('path/to/my/config.json');
atau untuk menggunakan objek JSON global untuk mem-parsing nilai string ke objek:
var stringContainingJson = '\"json that is obtained from somewhere\"';
var objectFromParse = JSON.parse(stringContainingJson);
perhatikan bahwa ketika Anda memerlukan file konten file itu dievaluasi, yang menimbulkan risiko keamanan jika itu bukan file json tetapi file js.
di sini, saya telah menerbitkan demo di mana Anda dapat melihat kedua metode dan bermain secara online (contoh parsing ada di file app.js - lalu klik tombol run dan lihat hasilnya di terminal): http: // staging1 .codefresh.io / labs / api / env / json-parse-example
Anda dapat memodifikasi kode dan melihat dampaknya ...
Menggunakan JSON untuk konfigurasi Anda dengan Node.js? Baca ini dan dapatkan keterampilan konfigurasi Anda lebih dari 9000 ...
Catatan: Orang yang mengklaim bahwa data = membutuhkan ('./ data.json'); adalah risiko keamanan dan meremehkan jawaban orang-orang dengan semangat yang bersemangat: Anda benar-benar salah . Coba letakkan non-JSON di file itu ... Node akan memberi Anda kesalahan, persis seperti itu jika Anda melakukan hal yang sama dengan yang lebih lambat dan sulit untuk membaca kode file manual dan kemudian JSON.parse (). Tolong hentikan penyebaran informasi yang salah; Anda menyakiti dunia, tidak membantu. Node dirancang untuk memungkinkan ini; itu bukan risiko keamanan!
Aplikasi yang tepat hadir dalam 3+ lapisan konfigurasi:
Sebagian besar pengembang memperlakukan konfigurasi server dan aplikasi mereka seolah-olah itu dapat berubah. Tidak bisa. Anda dapat lapisan perubahan dari lapisan yang lebih tinggi di atas satu sama lain, tetapi Anda memodifikasi persyaratan dasar . Beberapa hal perlu ada! Buat config Anda bertindak seperti itu tidak dapat diubah, karena beberapa di antaranya pada dasarnya, sama seperti kode sumber Anda.
Gagal melihat bahwa banyak barang Anda tidak akan berubah setelah startup mengarah ke anti-pola seperti mengotori pemuatan konfigurasi Anda dengan blok coba / tangkap, dan berpura-pura Anda dapat melanjutkan tanpa aplikasi pengaturan yang benar. Kamu tidak bisa Jika Anda bisa, itu termasuk dalam lapisan konfigurasi komunitas / pengguna, bukan lapisan konfigurasi server / aplikasi. Anda salah melakukannya. Barang-barang opsional harus berlapis di atas ketika aplikasi selesai bootstrapnya.
Berhenti membenturkan kepala ke dinding: Konfigurasi Anda harus sangat sederhana .
Lihatlah betapa mudahnya men-setup sesuatu yang kompleks seperti kerangka layanan protokol-agnostik dan data-agnostik menggunakan file konfigurasi json sederhana dan file app.js sederhana ...
container-config.js ...
{
"service": {
"type" : "http",
"name" : "login",
"port" : 8085
},
"data": {
"type" : "mysql",
"host" : "localhost",
"user" : "notRoot",
"pass" : "oober1337",
"name" : "connect"
}
}
index.js ... (mesin yang menggerakkan segalanya)
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 ... (kode yang mendukung layanan agnostik protokol-agnostik dan sumber data Anda)
module.exports = function(request, response){
response.end('Responding to: ' + request.url);
}
Dengan menggunakan pola ini, Anda sekarang dapat memuat hal-hal konfigurasi komunitas dan pengguna di atas aplikasi yang telah Anda boot, dev ops siap untuk mendorong pekerjaan Anda ke dalam wadah dan menskalakannya. Anda membaca untuk multitenant. Userland terisolasi. Anda sekarang dapat memisahkan masalah protokol layanan mana yang Anda gunakan, tipe database apa yang Anda gunakan, dan hanya fokus pada penulisan kode yang baik.
Karena Anda menggunakan lapisan, Anda dapat mengandalkan satu sumber kebenaran untuk semuanya, kapan saja (objek konfigurasi berlapis), dan menghindari pemeriksaan kesalahan di setiap langkah, khawatir tentang "oh sial, bagaimana saya akan membuat ini bekerja tanpa konfigurasi yang tepat?!? "
Solusi saya:
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
kesalahan - ada ide di mana harus mulai men-debug masalah ini?
Hanya ingin menyelesaikan jawabannya (karena saya berjuang untuk sementara waktu), ingin menunjukkan cara mengakses informasi json, contoh ini menunjukkan mengakses 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);
}
})
Hanya untuk membuat ini serumit mungkin, dan membawa paket sebanyak mungkin ...
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);
Ini memungkinkan Anda melakukan:
var dataPromise = readJsonFile("foo.json");
dataPromise.then(console.log);
Atau jika Anda menggunakan async / tunggu:
let data = await readJsonFile("foo.json");
Keuntungan menggunakan hanya readFileSync
adalah bahwa server Node Anda dapat memproses permintaan lain saat file sedang dibaca dari disk.
JSON.parse tidak akan memastikan keamanan string json yang Anda parsing. Anda harus melihat perpustakaan seperti json-safe-parse atau perpustakaan serupa.
Dari halaman npm json-safe-parse:
JSON.parse bagus, tetapi memiliki satu kelemahan serius dalam konteks JavaScript: ini memungkinkan Anda untuk menimpa properti yang diwarisi. Ini bisa menjadi masalah jika Anda mem-parsing JSON dari sumber yang tidak terpercaya (misalnya: pengguna), dan memanggil fungsi yang Anda harapkan ada.
Leverage fungsi upaya Lodash untuk mengembalikan objek kesalahan, yang dapat Anda tangani dengan fungsi 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
alih-alih hanya menggunakan _.attempt (JSON.parse, str)
Selalu pastikan untuk menggunakan JSON.parse di try catch block karena node selalu melempar Kesalahan Tidak Terduga jika Anda memiliki beberapa data yang rusak di json Anda, jadi gunakan kode ini alih-alih JSON sederhana.
try{
JSON.parse(data)
}
catch(e){
throw new Error("data is corrupted")
}
Jika Anda ingin menambahkan beberapa komentar di JSON Anda dan membolehkan koma tertinggal Anda mungkin ingin menggunakan implementasi di bawah ini:
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);
}
Perhatikan bahwa itu mungkin tidak berfungsi dengan baik jika Anda memiliki sesuatu seperti "abc": "foo // bar"
di JSON Anda. Jadi YMMV.
Jika file sumber JSON cukup besar, mungkin ingin mempertimbangkan rute asinkron melalui pendekatan async / tunggu asli dengan Node.js 8.0 sebagai berikut
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))
Saya menggunakan fs-extra . Saya sangat menyukainya karena - walaupun mendukung panggilan balik - juga mendukung Janji . Jadi itu hanya memungkinkan saya untuk menulis kode saya dengan cara yang lebih mudah dibaca:
const fs = require('fs-extra');
fs.readJson("path/to/foo.json").then(obj => {
//Do dome stuff with obj
})
.catch(err => {
console.error(err);
});
Ini juga memiliki banyak metode berguna yang tidak datang bersama dengan fs
modul standar dan , di atas itu, juga menjembatani metode dari fs
modul asli dan menjanjikannya.
CATATAN: Anda masih dapat menggunakan metode Node.js asli. Mereka dijanjikan dan disalin ke fs-extra. Lihat catatan pada
fs.read()
&fs.write()
Jadi pada dasarnya semua keuntungan. Saya harap orang lain menganggap ini berguna.
Jika Anda perlu mengurai JSON dengan Node.js dengan cara yang aman (alias: pengguna dapat memasukkan data, atau API publik) Saya akan menyarankan menggunakan secure-json-parse .
Penggunaannya seperti default JSON.parse
tetapi akan melindungi kode Anda dari:
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
Anda dapat menggunakan JSON.parse () (yang merupakan fungsi bawaan yang mungkin akan memaksa Anda untuk membungkusnya dengan pernyataan try-catch).
Atau gunakan pustaka npm parsing JSON, sesuatu seperti json-parse-atau
Gunakan ini untuk berada di sisi yang aman
var data = JSON.parse(Buffer.concat(arr).toString());
NodeJs adalah server berbasis JavaScript , sehingga Anda dapat melakukan hal itu dalam JavaScript murni ...
Bayangkan Anda memiliki Json ini di NodeJs ...
var details = '{ "name": "Alireza Dezfoolian", "netWorth": "$0" }';
var obj = JSON.parse(details);
Dan Anda dapat melakukannya di atas untuk mendapatkan versi parsing dari json Anda ...
Seperti yang disebutkan dalam jawaban di atas, Kita dapat menggunakan JSON.parse()
untuk mem-parsing string ke JSON. Tetapi sebelum mem-parsing, pastikan untuk mengurai data yang benar atau jika tidak, itu dapat menurunkan seluruh aplikasi Anda.
aman untuk menggunakannya seperti ini
let parsedObj = {}
try {
parsedObj = JSON.parse(data);
} catch(e) {
console.log("Cannot parse because data is not is proper json format")
}
Gunakan JSON.parse(str);
. Baca lebih lanjut di sini .
Berikut ini beberapa contohnya:
var jsonStr = '{"result":true, "count":42}';
obj = JSON.parse(jsonStr);
console.log(obj.count); // expected output: 42
console.log(obj.result); // expected output: true
Sederhana, Anda dapat mengonversi JSON menjadi menggunakan string JSON.stringify(json_obj)
, dan mengonversi string ke menggunakan JSON JSON.parse("your json string")
.