如何使用Node.jsparsingJSON?
我应该如何parsingJSON使用Node.js? 有一些模块会安全地validation和parsingJSON吗?
你可以简单地使用JSON.parse
。
node.js构build在V8上 ,它提供了全局对象JSON
[docs] 。 JSON
对象的定义是ECMAScript 5规范的一部分 。
注 – JSON.parse
可以绑定当前线程,因为它是一个同步方法。 所以,如果你打算parsing大JSON对象使用streamJSONparsing器。
你可以要求 .json文件。
var parsedJSON = require('./file-name');
例如,如果您的源代码文件所在的目录中有一个config.json
文件,您可以使用:
var config = require('./config.json');
或者(可以省略文件扩展名):
var config = require('./config');
请注意, require
是同步的 ,只有一次读取文件,接下来的调用将从caching中返回结果
另请注意,您只能在绝对控制下使用本地文件,因为它可能会执行文件中的任何代码。
你可以使用JSON.parse()
。
您应该可以在任何兼容ECMAScript 5的 JavaScript实现上使用JSON
对象。 而构buildNode.js的V8就是其中之一。
parsing包含JSON数据的string
var str = '{ "name": "John Doe", "age": 42 }'; var obj = JSON.parse(str);
parsing包含JSON数据的文件
你将不得不用fs
模块做一些文件操作。
asynchronous版本
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');
但是,我不推荐这么做,原因如下:
-
require
只会读取一次文件。 后续调用require
相同的文件将返回一个caching的副本。 如果您想读取持续更新的.json
文件,这不是一个好主意。 你可以使用黑客 。 但是在这一点上,简单地使用fs
更容易。 - 如果您的文件没有
.json
扩展名,那么require
不会将该文件的内容视为JSON。 -
require
是同步的。 如果你有一个非常大的JSON文件,它会窒息你的事件循环。 你真的需要用fs.readFile
来使用JSON.parse
。
认真! 使用JSON.parse
。
jsonfile
模块
如果您正在阅读大量的.json
文件(如果您非常懒惰),每次写入样板代码都会变得很烦人。 你可以使用jsonfile
模块保存一些字符。
var jf = require('jsonfile');
asynchronous版本
jf.readFile('/path/to/file.json', function(err, obj) { // obj contains JSON data });
同步版本
var obj = jf.readFileSync('/path/to/file.json');
从stream中parsingJSON
如果JSON内容通过networkingstream式传输,则需要使用stream式JSONparsing器。 否则,它将捆绑你的处理器,并扼杀你的事件循环,直到JSON内容完全stream式传输。
在NPM中有很多可用的包 。 select最适合你的。
error handling/安全性
如果您不确定是否传递给JSON.parse()
是有效的JSON ,请确保在try/catch
块内包含对JSON.parse()
的调用。 用户提供的JSONstring可能会导致应用程序崩溃,甚至可能导致安全漏洞。 确保在parsing外部提供的JSON时完成error handling。
使用JSON对象 :
JSON.parse(str);
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); });
我想提一下,有全球的JSON对象的替代品。 JSON.parse
和JSON.stringify
都是同步的,所以如果你想处理大对象,你可能需要检查一些asynchronousJSON模块。
看看: 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"));
有关“fs”库的更多信息,请参阅http://nodejs.org/api/fs.html上的文档;
既然你不知道你的string实际上是有效的,我会把它放进一个try catch。 另外,因为try catch块没有被节点优化,所以我会把整个东西放到另一个函数中:
function tryParseJson(str) { try { return JSON.parse(str); } catch (ex) { return null; } }
或“asynchronous风格”
function tryParseJson(str, callback) { process.nextTick(function () { try { callback(null, JSON.parse(str)); } catch (ex) { callback(ex) } }) }
parsing一个JSONstream? 使用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");
就这样。
正如在这里提到的其他答案,你可能要么需要一个本地的json文件,你知道这是安全的,目前,就像一个configuration文件:
var objectFromRequire = require('path/to/my/config.json');
或者使用全局JSON对象将string值parsing为对象:
var stringContainingJson = '\"json that is obtained from somewhere\"'; var objectFromParse = JSON.parse(stringContainingJson);
请注意,当你需要一个文件时,该文件的内容会被评估,如果它不是一个json文件,而是一个js文件,则会引入安全风险。
在这里,我已经发布了一个演示,你可以在这里看到两种方法,并在线玩(parsing的例子是在app.js文件 – 然后点击运行button,并在terminal中看到的结果): http:// staging1 .codefresh.io /实验室/ API / env的/ JSON-parsing-示例
您可以修改代码并查看影响…
这里的每个人都告诉过JSON.parse,所以我想说点别的。 有一个伟大的模块连接到许多中间件,使应用程序的开发更容易和更好。 其中一个中间件是bodyParser 。 它parsingJSON,HTML表单等。还有一个特定的JSONparsing中间件只有noop 。
看看上面的链接,这可能对你真的有帮助。
我的解决scheme
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); });
只是为了使这个尽可能复杂,并尽可能多地引入软件包…
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);
或者,如果您使用asynchronous/等待:
let data = await readJsonFile("foo.json");
与仅使用readFileSync
相比,其优点是您的节点服务器可以在文件从磁盘读取时处理其他请求。
JSON.parse不能保证你正在parsing的jsonstring的安全性。 你应该看看像json-safe-parse或类似库的库。
从json-safe-parse npm页面:
JSON.parse非常好,但是它在JavaScript的上下文中有一个严重的缺陷:它允许你重写inheritance的属性。 如果你从一个不信任的源(例如:一个用户)parsingJSON,并且调用你希望存在的函数,这可能会成为一个问题。
利用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
总是要确保在try catch块中使用JSON.parse,因为如果在json中有一些损坏的数据,那么节点总是会抛出一个意外错误,所以使用这个代码而不是简单的JSON.Parse
try{ JSON.parse(data) } catch(e){ throw new Error("data is corrupted") }
只是想完成答案(因为我挣扎了一段时间),想要展示如何访问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中添加一些注释,并且允许使用下面的实现:
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。
在Node.js中使用JSON进行configuration? 阅读并获得超过9000的configuration技能…
注意:声明data = require('./ data.json')的人; 是一种安全风险,用热忱的热忱来压低人们的答案:你是完全错误的 。 尝试在该文件中放置非JSON … Node会给你一个错误,就像你用同样的事情做了更慢更难的代码手动文件读取,然后后面的JSON.parse()。 请停止传播错误信息; 你伤害了世界,没有帮助。 节点被devise为允许这个; 这不是一个安全风险!
正确的应用程序有3 层以上的configuration:
- 服务器/容器configuration
- 应用程序configuration
- (可选)租户/社区/组织configuration
- 用户configuration
大多数开发人员将其服务器和应用程序configuration视为可以更改。 它不能。 您可以将更高层的更改层叠在一起,但是您正在修改基本要求 。 有些事情需要存在! 使你的configuration像不可变的一样,因为它的一些基本上就像你的源代码一样。
没有看到你的东西在启动后不会改变会导致反模式,例如乱扔你的configuration加载try / catch块,并假装你可以继续没有你正确的设置的应用程序。 你不能。 如果可以,那属于社区/用户configuration层,而不是服务器/应用程序configuration层。 你只是做错了。 当应用程序完成引导时,可选的东西应该放置在顶层。
不要把头撞在墙上:你的configuration应该是非常简单的 。
看看使用一个简单的jsonconfiguration文件和简单的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); }
使用这种模式,您现在可以在引导的应用程序之上加载社区和用户configuration的东西,开发工具已准备好将您的工作推到一个容器中并进行缩放。 你读了多租户。 用户区被隔离。 您现在可以分离您正在使用的服务协议的问题,您正在使用哪种数据库types,并专注于编写优质代码。
因为你正在使用图层,你可以随时依赖单一的事实来源(分层的configuration对象),并避免在每一步的错误检查,担心“哦,废话,我怎么做这个工作没有适当的configuration?!?“。
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
文件。
如果文件结尾不同,这是行不通的!
这很简单,您可以使用JSON.stringify(json_obj)
将JSON转换为string,并使用JSON.parse("your json string")
将string转换为JSON。
var fs = require('fs'); fs.readFile('ashish.json',{encoding:'utf8'},function(data,err) { if(err) throw err; else { console.log(data.toString()); } })