Как мне проанализировать JSON с помощью Node.js? Есть ли какой-нибудь модуль, который будет проверять и анализировать JSON безопасно?
Как мне проанализировать JSON с помощью Node.js? Есть ли какой-нибудь модуль, который будет проверять и анализировать JSON безопасно?
Ответы:
Вы можете просто использовать JSON.parse
.
Определение JSON
объекта является частью спецификации ECMAScript 5 . node.js построен на движке Google Chrome V8 , который соответствует стандарту ECMA. Следовательно, node.js также имеет глобальный объект [docs] .JSON
Примечание - JSON.parse
может связать текущий поток, потому что это синхронный метод. Поэтому, если вы планируете анализировать большие объекты JSON, используйте потоковый анализатор JSON.
Вы можете требовать файлы .json.
var parsedJSON = require('./file-name');
Например, если у вас есть config.json
файл в том же каталоге, что и файл исходного кода, который вы используете:
var config = require('./config.json');
или (расширение файла может быть опущено):
var config = require('./config');
обратите внимание , что require
это синхронное и читает только файл один раз , следующие вызовы возвращают результат из кэша
Также обратите внимание, что вы должны использовать это только для локальных файлов под вашим абсолютным контролем, так как он потенциально выполняет любой код в файле.
require
это синхронно. Если вы хотите использовать дружественное асинхронное использование fs.readFile
вместо этогоJSON.parse
.json
расширение! Если ваш файл НЕ имеет .json
расширения, require не будет обрабатывать его как файл json.
Вы можете использоватьJSON.parse()
.
Вы должны иметь возможность использовать JSON
объект в любой реализации JavaScript, совместимой с ECMAScript 5 . И V8 , на котором построен Node.js, является одним из них.
Примечание. Если вы используете файл 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
? Подумай еще раз!Иногда вы можете использоватьrequire
:
var obj = require('path/to/file.json');
Но я не рекомендую это по нескольким причинам:
require
синхронно Если у вас очень большой JSON-файл, он закроет ваш цикл событий. Вам действительно нужно использовать JSON.parse
с fs.readFile
.require
будет читать файл только один раз . Последующие обращения к 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 (нет, они не одинаковы). Так много для 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 не оптимизируются узлом, я бы поместил все это в другую функцию:
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, поэтому я подумал сказать что-то еще. Есть отличный модуль Connect со многими промежуточными программами, чтобы сделать разработку приложений проще и лучше. Одним из промежуточных программ является 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 / лаборатория / API / ENV / JSON-синтаксический анализ, например ,
Вы можете изменить код и увидеть влияние ...
Используете JSON для своей конфигурации с Node.js? Прочитайте это и получите навыки настройки более 9000 ...
Примечание. Люди, утверждающие, что data = require ('./ data.json'); это угроза безопасности, и люди с ревностным рвением опровергают ответы людей: вы совершенно и совершенно неправы . Попробуйте поместить не-JSON в этот файл ... Node выдаст вам ошибку, точно так же, как если бы вы делали то же самое с гораздо более медленным и трудным кодом для ручного чтения файла, а затем с последующим JSON.parse (). Пожалуйста, прекратите распространять дезинформацию; ты делаешь больно миру, а не помогаешь. Узел был разработан, чтобы позволить это; это не угроза безопасности!
Правильные приложения входят в 3+ уровня конфигурации:
Большинство разработчиков относятся к конфигурации своего сервера и приложения так, как будто они могут измениться. Не может Вы можете накладывать изменения из более высоких слоев друг на друга, но вы изменяете базовые требования . Некоторые вещи должны существовать! Сделайте так, чтобы ваш конфиг действовал так, как будто он неизменен, потому что некоторые из них, в основном, как ваш исходный код
Если вы не увидите, что многие вещи не изменятся после запуска, это приведет к анти-шаблонам, таким как засорение вашей конфигурации загрузкой блоков try / catch, и притворство, что вы можете продолжить работу без правильно настроенного приложения. Ты не можешь Если вы можете, это относится к уровню конфигурации сообщества / пользователя, а не к уровню конфигурации сервера / приложения. Вы просто делаете это неправильно. Необязательные элементы должны быть расположены сверху, когда приложение завершает загрузку.
Хватит биться головой об стену: ваш конфиг должен быть очень простым .
Посмотрите, как просто настроить такую сложную инфраструктуру, как независимая от протокола и независимой от источника данных служба, с помощью простого файла конфигурации json и простого файла app.js ...
контейнер-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);
}
Используя этот шаблон, вы теперь можете загружать файлы конфигурации сообщества и пользователей поверх загруженного приложения, dev ops готов поместить вашу работу в контейнер и масштабировать ее. Вы читаете за мультитенант. Userland изолирован. Теперь вы можете разделить вопросы о том, какой протокол службы вы используете, какой тип базы данных вы используете, и просто сосредоточиться на написании хорошего кода.
Поскольку вы используете слои, вы можете полагаться на единый источник правды для всего в любое время (многоуровневый объект конфигурации) и избегать проверок ошибок на каждом этапе, беспокоясь о "о, черт, как я собираюсь сделать это работать без правильной конфигурации?!? ".
Мое решение:
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
заключается в том, что ваш Node-сервер может обрабатывать другие запросы во время чтения файла с диска.
JSON.parse не обеспечит безопасность анализируемой строки json. Вы должны посмотреть на библиотеку, такую как json-safe-parse или похожую библиотеку.
Со страницы json-safe-parse npm:
JSON.parse великолепен, но у него есть один серьезный недостаток в контексте JavaScript: он позволяет переопределять унаследованные свойства. Это может стать проблемой, если вы анализируете 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.parse в блоке try catch, поскольку узел всегда генерирует непредвиденную ошибку, если в вашем json есть поврежденные данные, поэтому используйте этот код вместо простого JSON.Parse
try{
JSON.parse(data)
}
catch(e){
throw new Error("data is corrupted")
}
Если вы хотите добавить некоторые комментарии в ваш 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 довольно большой, возможно, стоит рассмотреть асинхронный маршрут с помощью нативного подхода async / await с Node.js 8.0 следующим образом
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 . Мне это очень нравится, потому что - хотя он поддерживает обратные вызовы - он также поддерживает обещания . Так что это просто позволяет мне писать свой код гораздо более читабельным способом:
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()
Так что это в основном все преимущества. Я надеюсь, что другие найдут это полезным.
Если вам нужно проанализировать JSON с Node.js безопасным способом (иначе: пользователь может вводить данные или через публичный 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 для анализа npm, что-то вроде json-parse-or
Используйте это, чтобы быть на безопасной стороне
var data = JSON.parse(Buffer.concat(arr).toString());
NodeJs - это сервер на основе JavaScript , так что вы можете делать то же самое, что и в чистом JavaScript ...
Представьте, что у вас есть этот Json в NodeJs ...
var details = '{ "name": "Alireza Dezfoolian", "netWorth": "$0" }';
var obj = JSON.parse(details);
И вы можете сделать выше, чтобы получить разобранную версию вашего JSON ...
Как уже упоминалось в ответах выше, мы можем использовать JSON.parse()
синтаксический анализ строк в JSON. Но перед синтаксическим анализом обязательно проанализируйте правильные данные, иначе это может привести к остановке всего приложения.
это безопасно использовать как это
let parsedObj = {}
try {
parsedObj = JSON.parse(data);
} catch(e) {
console.log("Cannot parse because data is not is proper json format")
}
Использование 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 в строку, используя JSON.stringify(json_obj)
, и конвертировать строку в JSON, используя JSON.parse("your json string")
.