最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Difference between JSON.parse() and eval() - Stack Overflow

programmeradmin1浏览0评论

May need a Javascript language lawyer for this one:

var s1 = "{\"x\":\"y:z\"}"

var o = JSON.parse(s1)
var s2 = JSON.stringify(o)

$('span#s').text(s1);
$('span#s2').text(s2);

if (s1 === s2) {
    $('span#areEqual').text('s1 === s2')
} else {
    $('span#areEqual').text('s1 !== s2')
}

JSON.parse(s2) // okay

$('span#jsonParse').text("JSON.parse(s2) okay")

eval(s2) // bad mojo!

$('span#eval').text("eval(s2) okay")

eval("("+s2+")") // bad mojo, too! 
$('span#eval2').text("eval((s2)) okay")

eval fails on s1, s2, and "("+s2+")".

jsFiddle here.

May need a Javascript language lawyer for this one:

var s1 = "{\"x\":\"y:z\"}"

var o = JSON.parse(s1)
var s2 = JSON.stringify(o)

$('span#s').text(s1);
$('span#s2').text(s2);

if (s1 === s2) {
    $('span#areEqual').text('s1 === s2')
} else {
    $('span#areEqual').text('s1 !== s2')
}

JSON.parse(s2) // okay

$('span#jsonParse').text("JSON.parse(s2) okay")

eval(s2) // bad mojo!

$('span#eval').text("eval(s2) okay")

eval("("+s2+")") // bad mojo, too! 
$('span#eval2').text("eval((s2)) okay")

eval fails on s1, s2, and "("+s2+")".

jsFiddle here.

Share Improve this question edited Feb 24, 2014 at 22:28 Jeff Lowery asked Feb 24, 2014 at 22:06 Jeff LoweryJeff Lowery 2,5992 gold badges32 silver badges43 bronze badges 21
  • 1 If you're asking why eval gives a SyntaxError, it's because that string doesn't represent a valid JavaScript program, which is what eval requres. – cookie monster Commented Feb 24, 2014 at 22:11
  • 1 @JeffLowery: No, JSON.parse() is a JSON parser. It accepts valid JSON, and doesn't care if it's a valid JS program. – cookie monster Commented Feb 24, 2014 at 22:12
  • 2 @JeffLowery: No. "The text must be wrapped in parens to avoid tripping on an ambiguity in JavaScript's syntax." – cookie monster Commented Feb 24, 2014 at 22:18
  • 1 @JeffLowery: Contrary to your claim, eval("("+s2+")") does not fail. – Chuck Commented Feb 24, 2014 at 22:30
  • 1 You put the one wrapped in parens below the one that has already failed. The execution stops when an error is thrown. – cookie monster Commented Feb 24, 2014 at 22:35
 |  Show 16 more ments

7 Answers 7

Reset to default 6

Your problem is that you mixing two unrelated things.

eval() is built-in javascript function, which main purpose is to interpret string of javascript code (thus make potentional security hole)

JSON.parse() function is for parse JSON string. Although very simmilar, do not make mistake, JSON is not Javascript and there are tiny differences. You should not use eval() for parsing JSON

What are the differences between JSON and JavaScript object?

$eval is automatically evaluated against a given scope.

For example:

$scope.a = 2;
var result = $scope.$eval('1+1+a');
// result is 4

$parse does not require scope. It takes an expression as a parameter and returns a function. The function can be invoked with an object that can resolve the locals:

For example:

var fn = $parse('1+1+a');
var result = fn({ a: 2 });
// result is 4

When you use eval for parsing JSON you need to wrap your expression with parentheses

eval('(' + s2 + ')');

jsfiddle

Check out what the specification says about JSON and eval http://www.json/js.html Notice this part specifically

The eval function is very fast. However, it can pile and execute any JavaScript program, so there can be security issues. The use of eval is indicated when the source is trusted and petent. It is much safer to use a JSON parser. In web applications over XMLHttpRequest, munication is permitted only to the same origin that provide that page, so it is trusted. But it might not be petent. If the server is not rigorous in its JSON encoding, or if it does not scrupulously validate all of its inputs, then it could deliver invalid JSON text that could be carrying dangerous script. The eval function would execute the script, unleashing its malice.

JSON is just a javascript object, and nothing more. Valid javascript could include functions, execution blocks, etc. If you just eval() a string, it could have code it in. JSON will parse if it's just JSON, but you can't know for sure by just stuffing it into eval. For example

var s = "(function(){ /* do badStuff */ return {s: 123, t: 456}; })()";
var result = eval(s);

Would give you a var result with the contents {s: 123, t: 456} but would also execute any code hidden in your function. If you were taking this input from elsewhere, code could be executing and not actually break anything on your end. Now the same example with JSON.parse

var result = JSON.parse(s);

It throws an error with the message:

Uncaught SyntaxError: Unexpected token ( 

So the parse saves you from remote code execution here, even if someone tried to sneak it in.

eval wasn't an expression - i've updated it to evaluate eval(s2 === s1); Otherwise it will try & execute what's within the eval & stop execution.

eval() attempts to evaluate a block of JavaScript code. If you had created a script file that started with the same text, you would have gotten the same error. In that context, I believe the braces signify a pound statement, as in an if-statement or for-statement body, but at the beginning of the pound statement is a string followed by a colon, which is not valid syntax.

If you wanted a string that would evaluate to an object, you'd have to enclose the object expression in parentheses to make it explicit that it's an expression. But as apocalypz says, you should not attempt to eval JSON. It's wrong on so many levels.

if you really want to use eval instead of JSON.parse() for parsing JSON then you should write something like

var o2; // declare o2 out of eval in case of "use strict"
eval("o2 = "+s1); // parse s1 and the assignment to the local o2
console.log(o2); // enjoy the local variable :)

...
发布评论

评论列表(0)

  1. 暂无评论