it-swarm.com.ru

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

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

894
Tikhon Jelvis

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

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

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

1029
Felix Kling

вы можете требовать .json файлы.

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

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

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

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

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

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

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

637
eliocs

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

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

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


Разбор строки, содержащей данные 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');

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

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

299
sampathsris

используйте объект JSON :

JSON.parse(str);
79
Mark Kahn

Еще один пример 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);
});
33
pyprism

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

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

32
Haider

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

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

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

28
Abhishek Verma

Поскольку вы не знаете, что ваша строка действительно допустима, я бы поставил ее сначала в попытку. Кроме того, поскольку блоки 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)
      }
    })
}
9
Vlad

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

8
Burcu Dogan
JSON.parse("your string");

Это все.

7
debianmaster

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

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

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

5
Saransh Mohapatra

Мое решение:

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);
});
5
Ravindra Galav

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

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

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

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

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

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

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

Посмотрите, как просто настроить такую ​​сложную инфраструктуру, как независимая от протокола и независимой от источника данных служба, с помощью простого файла конфигурации json и простого файла app.js ...

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

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

5
Nick Steele

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

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

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

3
mpen

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

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

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

2
Nux

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

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

Со страницы json-safe-parse npm: 

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

2
Timothy C. Quinn

Если исходный файл 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))
1
Lae Kettavong
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.');
1
vuhung3990

Я использую 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() 

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

1
Mig82

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

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

0
Sachin S

Как упоминалось в ответах выше, мы можем использовать JSON.parse() для анализа строк в JSON. Но перед синтаксическим анализом обязательно проанализируйте правильные данные, иначе это может привести к остановке всего приложения.

это безопасно использовать как это

let parsedObj = {}
try {
    parsedObj = JSON.parse(data);
} catch(e) {
    console.log("Cannot parse because data is not is proper json format")
}
0
Shekar Mania

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

var data = JSON.parse(Buffer.concat(arr).toString());
0
Victor Michael Kosgei

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

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

0
C'estLaVie

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

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

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

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

0
Alireza