Como processar o JSON usando o nó.js?
Como devo processar o JSON usando o nó.js? Há algum módulo que valide e partilhe o JSON de forma segura?
29 answers
Pode simplesmente usar JSON.parse
.
A definição do objecto JSON
faz parte da especificação ECMAScript 5. no.js é construído sobre o motor do Google Chrome V8 , que adere ao padrão ECMA. Portanto, nó.js também tem um objeto global JSON
[docs].
Nota - JSON.parse
pode amarrar a linha atual porque é um método síncrono. Então, se você está planejando processar grandes objetos JSON use um a transmitir o json parser.
Podeexigir .ficheiros json.
var parsedJSON = require('./file-name');
Por exemplo, se tiver um ficheiro config.json
na mesma pasta que o seu ficheiro de código-fonte, irá usar:
var config = require('./config.json');
Ou (a extensão do ficheiro pode ser omitida):
var config = require('./config');
note que require
é síncrona e apenas lê o arquivo depois, chamadas seguintes retornar o resultado da cache
observe também que você só deve usar isso para arquivos locais sob seu controle absoluto, como ele potencialmente executa qualquer código dentro do ficheiro.
Você pode usar JSON.parse()
.
Deverá ser capaz de usar o objecto JSON
em qualquer implementação JavaScript compatível com ECMAScript 5. E V8 , em que nó.o js está construído é um deles.
Analisar um texto contendo dados JSON
var str = '{ "name": "John Doe", "age": 42 }';
var obj = JSON.parse(str);
A analisar um ficheiro que contém dados JSON
Vais ter de fazer algumas operações de ficheiros com o módulofs
.
Assíncrono version
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);
});
Versão sincronizada
var fs = require('fs');
var json = JSON.parse(fs.readFileSync('/path/to/file.json', 'utf8'));
Queres usar require
? Pensa outra vez!
var obj = require('path/to/file.json');
Mas, não recomendo isto por várias razões:
Nota: Se estiver a utilizar um ficheiro JSON para guardar informações sensíveis (por exemplo, senhas), é a forma errada de o fazer. Vê como o Heroku consegue.: https://devcenter.heroku.com/articles/config-vars#setting-up-config-vars-for-a-deployed-application. descubra como sua plataforma faz isso, e use process.env
para recuperar os vars de configuração de dentro do Código.
-
require
é síncrono. Se você tem um arquivo JSON muito grande, ele vai sufocar o seu loop evento. Você realmente precisa usarJSON.parse
comfs.readFile
. -
require
irá ler o ficheiro só uma vez. As chamadas subsequentes pararequire
para o mesmo ficheiro Irão devolve uma cópia em cache. Não é uma boa idéia se você quiser ler um arquivo.json
que é continuamente atualizado. Dava-te jeito um hack. Mas neste momento, é mais fácil usar simplesmentefs
. - se o seu ficheiro não tiver uma extensão
.json
,require
não tratará o conteúdo do ficheiro como JSON.
A sério! Utilização JSON.parse
.
load-json-file
módulo
Se você está lendo um grande número de arquivos .json
, (e se você é extremamente preguiçoso), torna-se é irritante escrever códigos de rotura sempre. Você pode salvar alguns caracteres usando o load-json-file
módulo.
const loadJsonFile = require('load-json-file');
Versão assíncrona
loadJsonFile('/path/to/file.json').then(json => {
// `json` contains the parsed object
});
Versão sincronizada
let obj = loadJsonFile.sync('/path/to/file.json');
A processar JSON de riachos
Se o conteúdo JSON é transmitido através da rede, você precisa usar um streaming JSON parser. Caso contrário, ele vai amarrar o seu processador e sufocar o seu ciclo de eventos até o conteúdo JSON está totalmente streamed.
Há abundância de pacotes disponíveis em NPM para isto. Escolhe o que é melhor para ti.
Tratamento De Erros / Segurança
Se não tiver a certeza se o que quer que seja que foi passado para JSON.parse()
é válido JSON, certifique-se que encerra a chamada para JSON.parse()
dentro de um bloco try/catch
. Um usuário proveu que a cadeia de JSON poderia interromper sua aplicação, e até mesmo levar a falhas de segurança. Certifique-se de que o tratamento de erros é feito se você analisar o JSON fornecido externamente.
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.parse
e JSON.stringify
são ambos síncronos, por isso, se quiser lidar com grandes objectos, poderá querer verificar alguns dos módulos JSON assíncronos.
Dá uma vista de olhos: https://github.com/joyent/node/wiki/Modules#wiki-parsers-json
Inclui a biblioteca node-fs
.
var fs = require("fs");
var file = JSON.parse(fs.readFileSync("./PATH/data.json", "utf8"));
Para mais informações sobre a biblioteca 'fs', consulte a documentação em http://nodejs.org/api/fs.html
function tryParseJson(str) {
try {
return JSON.parse(str);
} catch (ex) {
return null;
}
}
Ou no "estilo async"
function tryParseJson(str, callback) {
process.nextTick(function () {
try {
callback(null, JSON.parse(str));
} catch (ex) {
callback(ex)
}
})
}
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("your string");
É tudo.
Como outras respostas aqui mencionadas, você provavelmente quer pedir um arquivo JSON local que você sabe que é seguro e presente, como um arquivo de configuração:
var objectFromRequire = require('path/to/my/config.json');
Ou para usar o objecto global JSON para processar um valor de cadeia num objecto:
var stringContainingJson = '\"json that is obtained from somewhere\"';
var objectFromParse = JSON.parse(stringContainingJson);
Note que quando você precisa de um arquivo o conteúdo desse arquivo é avaliado, o que introduz um risco de segurança no caso de não ser um arquivo json, mas um arquivo js.
Aqui, eu publiquei uma demo onde você pode ver ambos os métodos e jogue com eles online (O exemplo de análise está na aplicação.js file-em seguida, clique no botão Executar e ver o resultado no terminal): http://staging1.codefresh.io/labs/api/env/json-parse-example Pode modificar o código e ver o impacto...A minha solução:
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);
});
Só quero completar a resposta (como eu lutei com ela por um tempo), quero mostrar como acessar a informação json, este exemplo mostra acessar a matriz 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);
}
})
A usar o JSON para a sua configuração com o nó.js? Leia isso e obtenha suas habilidades de configuração acima de 9000...
Nota: pessoas que afirmam que os dados = requerem ('./dado.json'); é um risco de segurança e rebaixar as respostas das pessoas com zelo: você é exatamente e completamente errado. Tenta colocar o não-JSON nesse ficheiro... Node irá lhe dar um erro, exatamente como faria se você fizesse a mesma coisa com o muito mais lento e mais difícil de codificar o ficheiro manual e depois o JSON subsequente.analisar(). Por favor, pára de espalhar desinformação, estás a magoar o mundo, não estás a ajudar. Node was designed to allow this; it is not a security risk!
Existem aplicações adequadas. 3+ camadas de configuração:
- configuração do servidor/Contentor
- configuração da aplicação
- (facultativo) inquilino / comunidade / organização config
- utilizador config
A maioria dos programadores tratam o seu servidor e configuração do aplicativo como se ele pudesse mudar. Não pode. você pode mudar a camada de camadas mais altas em cima umas das outras, mas você está modificando os requisitos de base . Algumas coisas precisam de existir! Faz a tua configuração agir como se fosse imutável, porque parte dela é basicamente, tal como o teu código fonte.
Não ver que muitas das tuas coisas não vão mudar depois da inicialização levar a anti-padrões como enchendo o seu carregamento de configuração com blocos de tentativa/captura, e fingindo que pode continuar sem a sua aplicação de configuração adequada. Não pode. se puder, isso pertence à camada de configuração comunidade/utilizador, não à camada de configuração servidor / aplicação. Estás a fazer mal. O material opcional deve ser colocado em camadas no topo quando a aplicação termina é bootstrap. Para de bater com a cabeça contra a parede: a tua configuração deve ser ultra simples. Olha como é fácil. é configurar algo tão complexo como um protocolo-agnóstico e DataSource-agnostic service framework usando um arquivo de configuração json simples e app simples.ficheiro js...Container-config.js...
{
"service": {
"type" : "http",
"name" : "login",
"port" : 8085
},
"data": {
"type" : "mysql",
"host" : "localhost",
"user" : "notRoot",
"pass" : "oober1337",
"name" : "connect"
}
}
Índice.js... (O motor que alimenta tudo)
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... (o código que alimenta o seu protocolo-agnóstico e serviço agnóstico fonte de dados)
module.exports = function(request, response){
response.end('Responding to: ' + request.url);
}
Usando este padrão, você pode agora carregar coisas de configuração da comunidade e do utilizador em cima do seu app inicializada, o dev ops está pronto para enfiar o seu trabalho num contentor e escalá-lo. Você é lido para multitenant. Userland está isolado. Agora você pode separar as preocupações de que Protocolo de serviço você está usando, Que tipo de banco de dados você está usando, e apenas se concentrar em escrever um bom código.
Porque você está usando camadas, você pode confiar em uma única fonte de verdade para tudo, a qualquer momento (o objeto de configuração em camadas), e evitar verificações de erro em cada passo, preocupando - se com " oh merda, como eu vou para fazer isto funcionar sem uma configuração adequada?!?".
Só para tornar isto o mais complicado possível, e trazer o maior número possível de pacotes...
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);
Isto permite-te fazer:
var dataPromise = readJsonFile("foo.json");
dataPromise.then(console.log);
Ou se estiver a utilizar async / wait:
let data = await readJsonFile("foo.json");
A vantagem sobre apenas usar readFileSync
é que o seu servidor de nós pode processar outras solicitações enquanto o arquivo está sendo lido fora do disco.
Se quiser adicionar alguns comentários ao seu JSON e permitir vírgulas finais, poderá querer usar abaixo da implementação:
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);
}
Note que pode não funcionar bem se tiver algo como "abc": "foo // bar"
no seu JSON. Então ...
From json-safe-parse npm page:
JSON.o parse é grande, mas tem uma falha grave no contexto do JavaScript: permite-lhe sobrepor propriedades herdadas. Isto pode tornar-se um problema se estiver a analisar o JSON a partir de uma fonte não confiável (eg: um utilizador), e a invocar funções sobre ela, você esperaria existir.
Alavancar a função de tentativa do Lodash para retornar um objeto de erro, que você pode lidar com a função 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
Certifique-se sempre de usar o JSON.processar em Tente o bloco catch como nó, atire sempre um erro inesperado se tiver alguns dados corrompidos no seu json, por isso use este código em vez de simples JSON.Parse
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.');
Se o ficheiro de código JSON for bastante grande, pode querer considerar a rota assíncrona via async / aguardar aproximação com o nó.js 8.0 como se segue
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))
Isto tinha de ser gritado comigo: só funciona para arquivos .json
.
Se o fim do ficheiro é diferente isto não funciona!
Podes usar o JSON.parse () (que é uma função incorporada que provavelmente irá forçá-lo a embrulhá-la com declarações de tentativa de captura).
Ou usar uma biblioteca npm do JSON parsing, algo como json-parse-or
Use isto para estar do lado seguro
Var data = JSON.parse (Buffer.concat (arr).toString ());
Usa o JSON.parse (str);
Saber mais - JSON.processar()
Exemplo -
var jsonStr = '{"result":true, "count":42}';
obj = JSON.parse(jsonStr);
console.log(obj.count); //expected output: 42
console.log(obj.result); // expected output: true
Não é necessário mais módulos.
Basta usarvar parsedObj = JSON.parse(yourObj);
Acho que há problemas de segurança em relação a isto.
É simples, você pode converter JSON para string usando {[[0]}, e converter string para JSON usando 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());
}
})