Как разобрать JSON с помощью узла.Яш?

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

29 ответов


вы можете просто использовать JSON.parse.

определение JSON объект является частью спецификации ECMAScript 5. узел.js построен наV8 двигатель, который придерживается стандарта ECMA. Следовательно, узел.js также имеет глобальный объект JSON[docs].

Примечание - JSON.parse может связать текущий поток, потому что это синхронный метод. Поэтому, если вы планируете анализировать большие объекты JSON, используйте потоковый парсер json.


вы можете требуются .файлы json.

var parsedJSON = require('./file-name');

например, если у вас есть config.json файл в том же каталоге, что и файл исходного кода, который вы бы использовали:

var config = require('./config.json');

или (расширение файла можно не указывать):

var config = require('./config');

отметим, что require is синхронно и только читает файл после, следующие вызовы возвращают результат из кэша

также обратите внимание, что вы должны использовать только это для локальных файлов под вашим абсолютным контролем, поскольку он потенциально выполняет любой код в файле.


можно использовать JSON.parse().

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

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


Обработка Ошибок/Безопасности

если вы не уверены, что передают JSON.parse() is действительный JSON, не забудьте приложить вызов JSON.parse() внутри try/catch блок. Предоставленный пользователь Строка JSON может привести к сбою вашего приложения и даже может привести к дырам в безопасности. Убедитесь, что обработка ошибок выполняется, если вы анализируете JSON, предоставленный извне.


использовать объект JSON:

JSON.parse(str);

еще один пример JSON.разбор:

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


включить node-fs библиотека.

var fs = require("fs");
var file = JSON.parse(fs.readFileSync("./PATH/data.json", "utf8"));

подробнее о 'библиотека ФС', см. документацию на 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
    }))

https://github.com/dominictarr/JSONStream


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.

вот, я опубликовал демо, где вы можно видеть оба метода и играть с ними онлайн (пример разбора находится в приложении.JS файл-затем нажмите на кнопку run и посмотреть результат в терминале): http://staging1.codefresh.io/labs/api/env/json-parse-example

вы можете изменить код и увидеть удар...


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

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


мое решение:

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:

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);
  }
})

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

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

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

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

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

неспособность увидеть, что много ваших вещей не изменится после запуска приводит к анти-шаблонам, таким как засорение загрузки конфигурации блоками try/catch и притворство, что вы можете продолжить без правильно настроить приложение. Ты не можешь. Если можно, это относится к уровню конфигурации сообщества / пользователя, а не к уровню конфигурации сервера/приложения. Ты просто делаешь это неправильно. Опционный материал должен быть наслоен поверх когда применение заканчивает его загрузчик.

перестаньте биться головой о стену: ваша конфигурация должна быть ультра простой.

посмотрите, как легко настроить что-то сложное, как протокол-агностик и источник данных-агностик Service framework с помощью простого файла конфигурации json и простого приложения.файл js...

контейнер-конфиг.js...

{
    "service": {
        "type"  : "http",
        "name"  : "login",
        "port"  : 8085
    },
    "data": {
        "type"  : "mysql",
        "host"  : "localhost",
        "user"  : "notRoot",
        "pass"  : "oober1337",
        "name"  : "connect"
    }
}

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

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


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

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 и разрешить конечные запятые, которые вы можете использовать ниже implemention:

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

из страницы npm JSON-safe-parse:

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

всегда обязательно используйте JSON.разбор в попробовать поймать block as node всегда выдает непредвиденную ошибку, если у вас есть поврежденные данные в вашем json, поэтому используйте этот код вместо простого JSON.Разбор

try{
     JSON.parse(data)
}
catch(e){
   throw new Error("data is corrupted")
  }

var array={
    Action: 'Login',
    ErrorCode: 3,
    Detail: 'Your account not found.'
};
var http=require('http'),
    PORT=8789,
    server=function(req,res){
        res.writeHead(200,{'Content-Type':'application/json'});

        // JSON
        res.end(JSON.stringify(array));
    }

http.createServer(server).listen(PORT);
console.log('Server started.');

если исходный файл JSON довольно большой, может потребоваться рассмотреть асинхронный маршрут через собственный подход async / await с узлом.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))

Это нужно было кричать на меня: это работает только для .json файлы.

если окончание файла отличается, это не работает!


вы можете использовать JSON.parse () (который является встроенной функцией, которая, вероятно, заставит вас обернуть ее операторами try-catch).

или используйте некоторую библиотеку npm разбора JSON, что-то вроде JSON-parse-or


используйте это, чтобы быть в безопасности

дисп данные = формат JSON.разбор (буфер.concat (arr).toString ());


используйте JSON.parse (str);

узнать больше в формате JSON.parse ()

пример

var jsonStr = '{"result":true, "count":42}';

obj = JSON.parse(jsonStr);

console.log(obj.count);    //expected output: 42
console.log(obj.result);   // expected output: true

никаких дополнительных модулей не требуется.
Просто используйте
var parsedObj = JSON.parse(yourObj);
Я не думаю, что есть какие-либо проблемы безопасности в отношении этого


это просто, вы можете преобразовать JSON в строку, используя JSON.stringify(json_obj), и преобразовать строку в JSON с помощью JSON.parse("your json string").


var fs = require('fs');

fs.readFile('ashish.json',{encoding:'utf8'},function(data,err) {

   if(err) 
      throw err;

   else {

   console.log(data.toString());

 }
})