简体   繁体   中英

Difference between JSON.parse() and eval()

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 .

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.org/js.html Notice this part specifically

The eval function is very fast. However, it can compile and execute any JavaScript program, so there can be security issues. The use of eval is indicated when the source is trusted and competent. It is much safer to use a JSON parser. In web applications over XMLHttpRequest, communication is permitted only to the same origin that provide that page, so it is trusted. But it might not be competent. 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 compound statement, as in an if-statement or for-statement body, but at the beginning of the compound 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 :)

...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM