Как разбирать JSON с помощью Node.js?

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

Ответы

Ответ 1

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

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

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

Ответ 2

вы можете require.json файлы.

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

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

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

или (расширение файла может быть опущено):

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

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

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

Ответ 3

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

Вы должны иметь возможность использовать объект JSON в любой реализации JavaScript, совместимой с ECMAScript 5. И V8, на котором построен Node.js, является одним из них.


Разбор строки, содержащей данные JSON

var str = '{ "name": "John Doe", "age": 42 }';
var obj = JSON.parse(str);

Разбор файла, содержащего данные JSON

Вам придется выполнить некоторые файловые операции с модулем 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');

Но я не рекомендую это по нескольким причинам:

Примечание. Если вы используете файл JSON для хранения конфиденциальной информации (например, паролей), это неправильный способ сделать это. Посмотрите, как Heroku делает это: https://devcenter.heroku.com/articles/config-vars#setting-up-config-vars-for-a-deployed-application. Узнайте, как ваша платформа это делает, и используйте process.env для получения конфигурационных переменных из кода.

  1. require синхронно. Если у вас очень большой JSON файл, он захлебнется в вашем цикле событий. Вам действительно нужно использовать JSON.parse с fs.readFile.
  2. require будет прочитать файл только один раз. Последующие вызовы, require для того же файла, вернут кэшированную копию. Не очень хорошая идея, если вы хотите прочитать файл .json который постоянно обновляется. Вы могли бы использовать взломать. Но с этого момента проще просто использовать fs.
  3. Если ваш файл не имеет расширения .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. В противном случае он свяжет ваш процессор и закроет цикл обработки событий, пока содержимое JSON не будет полностью передано.

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


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

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

Ответ 5

Другой пример 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);
});

Ответ 6

Я хотел бы упомянуть, что есть альтернативы глобальному объекту JSON. JSON.parse и JSON.stringify являются синхронными, поэтому, если вы хотите иметь дело с большими объектами, вы можете проверить некоторые из асинхронных модулей JSON.

Посмотрите: https://github.com/joyent/node/wiki/Modules#wiki-parsers-json

Ответ 7

Включите библиотеку node-fs.

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

Для получения дополнительной информации о библиотеке fs см. документацию по адресу http://nodejs.org/api/fs.html

Ответ 8

Поскольку вы не знаете, что ваша строка действительно действительна, я бы поставил ее сначала в try catch. Кроме того, поскольку блоки try catch не оптимизированы с помощью node, я бы поставил все это в другую функцию:

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

Ответ 9

Разбор потока 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

Ответ 10

JSON.parse("your string");

Что все.

Ответ 11

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

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

Ответ 12

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

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

Ответ 13

Мое решение:

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

Ответ 14

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

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/wait:

let data = await readJsonFile("foo.json");

Преимущество только при использовании readFileSync заключается в том, что ваш сервер Node может обрабатывать другие запросы, пока файл считывается с диска.

Ответ 15

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

Ответ 16

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

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

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

  • Конфигурация сервера/контейнера
  • Конфигурация приложения
  • (необязательно) Конфиденциальность/Сообщество/Конфигурация организации
  • Конфигурация пользователя

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

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

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

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

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

Ответ 17

Если вы хотите добавить комментарии в свой 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);
}

Обратите внимание, что это может не сработать, если в вашем JSON есть что-то вроде "abc": "foo // bar". Итак, YMMV.

Ответ 18

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

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

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

Ответ 19

Использовать функцию попытки 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

Ответ 20

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

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

Ответ 21

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.');

Ответ 22

Если исходный файл 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))

Ответ 23

Я использую фс-экстра. Мне это очень нравится, потому что -although он поддерживает callbacks-, он также поддерживает 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()

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

Ответ 24

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

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

Ответ 25

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

var data = JSON.parse(Buffer.concat(arr).toString());

Ответ 26

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

Ответ 27

NodeJs - это сервер на основе JavaScript, так что вы можете делать то же самое, что и в чистом JavaScript...

Представьте, что у вас есть этот Json в NodeJs...

var details = '{ "name": "Alireza Dezfoolian", "netWorth": "$0" }';
var obj = JSON.parse(details);

И вы можете сделать выше, чтобы получить разобранную версию вашего JSON...

Ответ 28

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

Ответ 29

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

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

Ответ 30

Используйте 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