Как мне проанализировать 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 там, где вы их анализируете.
requireJSON?» и даже не стал документировать побочные эффекты. Это также означало, что 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").