Как разобрать JSON с помощью Node.js? - PullRequest
919 голосов
/ 20 апреля 2011

Как мне проанализировать JSON с помощью Node.js?Есть ли какой-нибудь модуль, который будет проверять и анализировать JSON безопасно?

Ответы [ 31 ]

6 голосов
/ 05 января 2015

Как уже упоминалось в других ответах, вы, вероятно, захотите либо потребовать локальный файл 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

Вы можете изменить код и увидеть влияние ...

6 голосов
/ 05 июля 2013

Все здесь рассказывали о JSON.parse, поэтому я подумал сказать что-то еще.Есть отличный модуль Connect со множеством промежуточного программного обеспечения, чтобы сделать разработку приложений проще и лучше.Одним из промежуточных программ является bodyParser .Он анализирует JSON, html-формы и т. Д. Существует также специальное промежуточное ПО для анализа только JSON noop .

Взгляните на ссылки выше, это может быть очень полезно для вас.

5 голосов
/ 04 января 2017

Использование JSON для конфигурации с Node.js? Прочитайте это и получите навыки настройки более 9000 ...

Примечание. Люди, утверждающие, что data = require ('./ data.json'); это Угроза безопасности и отрицательный ответ людей с рьяным усердием: Вы совершенно и полностью не правы . Попробуйте поместить не-JSON в этот файл ... Node выдаст вам ошибку, точно , как если бы вы сделали то же самое с намного медленнее и труднее кодировать файл руководства прочитайте и затем последующий JSON.parse (). Пожалуйста, прекратите распространять дезинформацию; ты делаешь больно миру, а не помогаешь. Узел был разработан , чтобы позволить это; это не угроза безопасности!

Правильное применение поставляется в 3+ слоях конфигурации:

  1. Конфигурация сервера / контейнера
  2. Конфигурация приложения
  3. (необязательно) Конфигурация клиента / сообщества / организации
  4. Конфиг пользователя

Большинство разработчиков относятся к конфигурации своего сервера и приложения так, как будто они могут измениться. Не может Вы можете изменять слои с более высоких слоев друг на друга, но вы изменяете базовые требования . Некоторым вещам нужно для существования! Сделайте так, чтобы ваш конфиг действовал так, как будто он неизменен, потому что в некоторой степени он так же, как и ваш исходный код.

Если вы не увидите, что многие ваши вещи не изменятся после запуска, это приведет к появлению анти-паттернов, таких как засорение вашей конфигурации загрузкой с помощью блоков 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 изолирован. Теперь вы можете разделить вопросы о том, какой протокол службы вы используете, какой тип базы данных вы используете, и просто сосредоточиться на написании хорошего кода.

Поскольку вы используете слои, вы можете полагаться на единый источник правды для всего, в любое время (многослойный объект конфигурации), и избегать проверок ошибок на каждом шагу, беспокоясь о, о, черт, как я собираюсь чтобы этот работал без надлежащей настройки?!? ".

4 голосов
/ 31 июля 2016

Просто хочу завершить ответ (как я некоторое время боролся с ним), хочу показать, как получить доступ к информации 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);
  }
})
4 голосов
/ 21 января 2015

Мое решение:

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);
});
3 голосов
/ 20 мая 2016

Просто, чтобы сделать это как можно более сложным и ввести как можно больше пакетов ...

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 может обрабатывать другие запросы во время чтения файла с диска.

2 голосов
/ 25 декабря 2015

Всегда обязательно используйте JSON.parse в блоке try catch , так как узел всегда генерирует непредвиденную ошибку, если в вашем json-файле есть поврежденные данные, поэтому используйте этот код вместо простого JSON.Parse

try{
     JSON.parse(data)
}
catch(e){
   throw new Error("data is corrupted")
  }
2 голосов
/ 20 января 2015

JSON.parse не обеспечит безопасность анализируемой строки json.Вы должны посмотреть на такую ​​библиотеку, как json-safe-parse или похожую библиотеку.

На странице nson json-safe-parse:

JSON.parseэто здорово, но у него есть один серьезный недостаток в контексте JavaScript: он позволяет переопределять унаследованные свойства.Это может стать проблемой, если вы анализируете JSON из ненадежного источника (например, пользователя) и вызываете для него функции, которые, как вы ожидаете, существуют.

2 голосов
/ 05 ноября 2015

Используйте функцию попытки 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
1 голос
/ 30 ноября 2018

Я использую fs-extra .Мне это очень нравится, потому что - хотя он поддерживает обратные вызовы - он также поддерживает Promises .Так что это просто позволяет мне писать свой код гораздо более читабельным способом:

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()

Так что это в основном все преимущества.Я надеюсь, что другие найдут это полезным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...