Join the Stack Overflow Community
Stack Overflow is a community of 6.4 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

How should I parse JSON using Node.js? Is there some module which will validate and parse JSON securely?

share|improve this question
    
you need to import jsonParse module via npm's package json file – Muhammad Umer Jul 30 at 22:22

23 Answers 23

up vote 790 down vote accepted

You can simply use JSON.parse.

node.js is built on V8, which provides the global object JSON[docs]. The definition of the JSON object is part of the ECMAScript 5 specification.

Note - JSON.parse can tie up the current thread because it is a synchronous method. So if you are planning to parse big JSON objects use a streaming json parser.

share|improve this answer
2  
Didn't think of that--I guess I haven't done enough JavaScript in the browser... – Tikhon Jelvis Apr 20 '11 at 7:14
    
Oops, too much editing going on. – Tikhon Jelvis Apr 20 '11 at 7:15
    
@TikhonJelvis: No worries :D – Felix Kling Apr 20 '11 at 7:16
27  
@snapfractalpop: The documentation only describes functions, etc, which are part of node.js. Standard JavaScript features are part of V8, node.js is built on. I updated the answer accordingly. – Felix Kling Mar 21 '12 at 19:09
1  
@FelixKling For what it's worth, there's a bunch of stuff here on node's github wiki: github.com/joyent/node/wiki/… – damianb Mar 18 '13 at 18:18

you can require .json files.

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

For example if you have a config.json file in the same directory as your source code file you would use:

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

or (file extension can be omitted):

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

note that require is synchronous and only reads the file once, following calls return the result from cache

Also note You should only use this for local files under your absolute control, as it potentially executes any code within the file.

share|improve this answer
4  
If you are using this method to parse the file make sure to take the path into account for the require. For example, you might need to do something like this: require './file-name-with-no-extension' (for example if the file is in the current directory) – SnapShot Jun 20 '12 at 21:36
76  
Note that the response is cached. E.g. if you put above require call in a function, call the function, change the JSON file, and call the function again, you'll get the old version of the JSON file. Has caught me out a couple of times! – Ben Clayton Apr 9 '13 at 20:42
13  
Note also that require is synchronous. If you want to async friendly use fs.readFile instead with JSON.parse – Evan Moran Aug 25 '13 at 21:57
21  
Will this approach just treat the file as JavaScript, thus potentially running arbitrary code in the .json file? – d11wtq Jul 27 '14 at 1:25
7  
Simple note: don't forget to use the .json extension! If your file does NOT have the .json extension, require will not treat it as a json file. – Jason Jan 21 '15 at 12:46

You can use JSON.parse().

You should be able to use the JSON object on any ECMAScript 5 compatible JavaScript implementation. And V8, upon which Node.js is built is one of them.


Parsing a string containing JSON data

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

Parsing a file containing JSON data

You'll have to do some file operations with fs module.

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

Synchronous version

var fs = require('fs');
var json = JSON.parse(fs.readFileSync('/path/to/file.json', 'utf8'));

You wanna use require? Think again!

You can sometimes use require:

var obj = require('path/to/file.json');

But, this is not recommended for several reasons:

  1. require will read the file only once. Subsequent calls to require for the same file will return a cached copy. Not a good idea if you want to read a .json file that is continuously updated. You could use a hack. But at this point, it's easier to simply use fs.
  2. If your file does not have a .json extension, require will not treat the contents of the file as JSON.
  3. require is synchronous. If you have a very big JSON file, it will choke your event loop. You really need to use JSON.parse with fs.readFile.

Seriously! Use JSON.parse.


jsonfile module

If you are reading large number of .json files, (and if you are extremely lazy), it becomes annoying to write boilerplate code every time. You can save some characters by using the jsonfile module.

var jf = require('jsonfile');

Asynchronous version

jf.readFile('/path/to/file.json', function(err, obj) {
  // obj contains JSON data
});

Synchronous version

var obj = jf.readFileSync('/path/to/file.json');

Parsing JSON from streams

If the JSON content is streamed over the network, you need to use a streaming JSON parser. Otherwise it will tie up your processor and choke your event loop until JSON content is fully streamed.

There are plenty of packages available in NPM for this. Choose what's best for you.


Error Handling/Security

If you are unsure if whatever that is passed to JSON.parse() is valid JSON, make sure to enclose the call to JSON.parse() inside a try/catch block. A user provided JSON string could crash your application, and could even lead to security holes. Make sure error handling is done if you parse externally-provided JSON.

share|improve this answer
    
and could even lead to security holes out of curiosity, how? – natario Oct 28 at 11:01
    
@natario: We are talking about server-side JS here. Suppose someone is parsing user-supplied JSON. If the assumption is that the JSON is always well formed, an attacker can send some malformed JSON to trigger an error, which if spilled to the client side, may reveal vital information about the system. Or if the JSON was both malformed and contained some text with <script>..., and the error is spilled to the client side, you have an XSS bug right there. Therefore IMO it's important to handle JSON errors right where you parse it. – Krumia Oct 28 at 11:11
    
Very clear, thank you. – natario Oct 28 at 11:27

use the JSON object:

JSON.parse(str);
share|improve this answer
7  
This just duplicates the top answer. Please consider deleting it; you'll keep the points. – Dan Dascalescu Nov 25 '14 at 6:59
6  
This answer has 50 upvotes. According to the 1% rule, probably 5000 users have spent time reading this answer, which adds nothing to the top one. The fact that it's 3 years old only makes the problem worse :) – Dan Dascalescu Nov 28 '14 at 21:00
9  
@DanDascalescu -- If you'll notice, the two answers were posted at exactly the same time 3 years ago. They both provide the same information. This is the case all over SO, I'm not about to go culling half of my answers just because they weren't the accepted answer. – zyklus Nov 28 '14 at 22:25
5  
@DanDascalescu -- So you're adding noise unless people do what you say. I disagree with your opinion, and so you are accomplishing absolutely nothing other than adding noise. – zyklus Nov 29 '14 at 21:24
4  
I for one found this series of comments fairly interesting but the answer itself to be a waste of my time. ...I'm not sure if that implies that the answer should be deleted, because then I wouldn't have seen the comment thread. But otherwise I'd say yeah. – MalcolmOcean Apr 6 '15 at 13:20

Another example of 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);
});
share|improve this answer
2  
I like that this approach does not require the json file to be local to the application. Thank you! – Charles Brandt May 8 '14 at 16:52

I'd like to mention that there are alternatives to the global JSON object. JSON.parse and JSON.stringify are both synchronous, so if you want to deal with big objects you might want to check out some of the asynchronous JSON modules.

Have a look: https://github.com/joyent/node/wiki/Modules#wiki-parsers-json

share|improve this answer
    
This is especially true if one expects JSON data from incoming connections. If malformed JSON is being parsed by JSON.parse your whole application is going to crash or, using process.on('uncaughtException', function(err) { ... });, there will eventually be no chance to send a "malformed JSON" error to the user. – Paul Feb 2 '13 at 11:25
2  
Which one is async parser ? I did not find it. – bxshi Feb 4 '13 at 9:33
1  
The linked page is now marked "DEPRECATED" and describes itself as a "faded relic". – Andrew Medico May 8 '14 at 4:56
    
Alternative github.com/dominictarr/JSONStream – Mike Stead Nov 10 '15 at 5:27

Include the node-fs library.

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

For more info on 'fs' library , refer the documentation at http://nodejs.org/api/fs.html

share|improve this answer
2  
It might be worth noting that you should wrap your var file line in a try/catch just in case your JSON fails to parse or the file does not exist. – Fostah Sep 17 '14 at 17:38
3  
Or just use a callback! – lawx Dec 25 '14 at 2:26

Since you don't know that your string is actually valid, I would put it first into a try catch. Also since try catch blocks are not optimized by node, i would put the entire thing into another function:

function tryParseJson(str) {
    try {
        return JSON.parse(str);
    } catch (ex) {
        return null;
    }
}

OR in "async style"

function tryParseJson(str, callback) {
    process.nextTick(function () {
      try {
          callback(null, JSON.parse(str));
      } catch (ex) {
          callback(ex)
      }
    })
}
share|improve this answer
2  
I just want to make a note that process.nextTick is not aysnc. It's just putting off reading the file until the next function call in the JS event loop. To run JSON.parse asynchronously you have use a different thread than the main Node.js thread – Alexander Mills Jun 8 '15 at 5:36

Parsing a JSON stream? Use 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

share|improve this answer
JSON.parse("your string");

That's all.

share|improve this answer

as other answers here have mentioned, you probably want to either require a local json file that you know is safe and present, like a configuration file:

var objectFromRequire = require('path/to/my/config.json'); 

or to use the global JSON object to parse a string value into an object:

var stringContainingJson = '\"json that is obtained from somewhere\"';
var objectFromParse = JSON.parse(stringContainingJson);

note that when you require a file the content of that file is evaluated, which introduces a security risk in case it's not a json file but a js file.

here, i've published a demo where you can see both methods and play with them online (the parsing example is in app.js file - then click on the run button and see the result in the terminal): http://staging1.codefresh.io/labs/api/env/json-parse-example

you can modify the code and see the impact...

share|improve this answer
    
Upvote for use of require() – fionbio Apr 1 '15 at 2:25

Everybody here has told about JSON.parse, so I thought of saying something else. There is a great module Connect with many middleware to make development of apps easier and better. One of the middleware is bodyParser. It parses JSON, html-forms and etc. There is also a specific middleware for JSON parsing only noop.

Take a look at the links above, it might be really helpful to you.

share|improve this answer

My solution:

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);
});
share|improve this answer

Just to make this as complicated as possible, and bring in as many packages as possible...

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

This lets you do:

var dataPromise = readJsonFile("foo.json");
dataPromise.then(console.log);

Or if you're using async/await:

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

The advantage over just using readFileSync is that your Node server can process other requests while the file is being read off disk.

share|improve this answer
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.');
share|improve this answer

JSON.parse will not ensure safety of json string you are parsing. You should look at a library like json-safe-parse or a similar library.

From json-safe-parse npm page:

JSON.parse is great, but it has one serious flaw in the context of JavaScript: it allows you to override inherited properties. This can become an issue if you are parsing JSON from an untrusted source (eg: a user), and calling functions on it you would expect to exist.

share|improve this answer

Leverage Lodash's attempt function to return an error object, which you can handle with the isError function.

// 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
share|improve this answer
1  
Can you explain why you added .bind instead of just using _.attempt(JSON.parse, str) – ish2f4f Sep 2 at 22:39

Always be sure to use JSON.parse in try catch block as node always throw an Unexpected Error if you have some corrupted data in your json so use this code instead of simple JSON.Parse

try{
     JSON.parse(data)
}
catch(e){
   throw new Error("data is corrupted")
  }
share|improve this answer

Just want to complete the answer (as I struggled with it for a while), want to show how to access the json information, this example shows accessing 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);
  }
})

share|improve this answer

If you want to add some comments in your JSON and allow trailing commas you might want use below 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);
}

Note that it might not work well if you have something like "abc": "foo // bar" in your JSON. So YMMV.

share|improve this answer

It's simple, you can convert JSON to string using JSON.stringify(json_obj), and convert string to JSON using JSON.parse("your json string").

share|improve this answer
2  
Have you looked at the top answer for this question? It's 3 years old and very complete. What were you hoping to contribute with the trivial information you're offering here? – Robby Cornelissen Jun 27 '14 at 3:10
2  
Now, now, let's not hold a double standard – danielmhanover Jul 20 '14 at 19:04
var fs = require('fs');

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

   if(err) 
      throw err;

   else {

   console.log(data.toString());

 }
})
share|improve this answer
    
While this may be an answer, please provide some context and explanation. Code only answers are not very useful for future visitors.. and may be deleted. – Jayan Dec 6 '15 at 5:22

This had to be shouted at me: it only works for .json files.

If the file ending is different this does not work!

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.