JSON.parse()和eval()之间的区别

时间:2014-02-24 22:06:37

标签: javascript json

这个可能需要一个Javascript语言律师:

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

evals1s2"("+s2+")"上失败。

jsFiddle here

7 个答案:

答案 0 :(得分:6)

你的问题是你混合了两个不相关的东西。

eval()是内置的javascript函数,其主要目的是解释javascript代码的字符串(从而产生潜在的安全漏洞)

JSON.parse()函数用于解析JSON字符串。虽然非常相似,但不要弄错,JSON不是Javascript并且存在微小的差异。 您不应使用 eval()来解析JSON

What are the differences between JSON and JavaScript object?

答案 1 :(得分:2)

根据给定范围自动评估

$eval

例如:

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

$parse不需要范围。它将表达式作为参数并返回一个函数。可以使用可以解析本地的对象来调用该函数:

例如:

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

答案 2 :(得分:1)

当您使用eval解析JSON时,您需要用括号包装表达式

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

jsfiddle

答案 3 :(得分:1)

查看规范中有关JSON和eval的内容 http://www.json.org/js.html 请特别注意这部分

  

eval功能非常快。但是,它可以编译和执行   任何JavaScript程序,都可能存在安全问题。指某东西的用途   当来源可信并且胜任时,将显示eval。它很多   更安全地使用JSON解析器。在XMLHttpRequest的Web应用程序中,   通信只允许提供相同的来源   页面,所以它是值得信赖的。但它可能没有能力。如果是服务器   它的JSON编码不严谨,或者它不严格   验证其所有输入,然后它可以提供无效的JSON文本   这可能是危险的脚本。 eval函数会   执行脚本,释放它的恶意。

JSON只是一个javascript对象,仅此而已。有效的javascript可以包括函数,执行块等。如果你只是eval()一个字符串,它可能有代码。如果它只是JSON,JSON会解析,但是你只能将它填入EVAL。例如

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

会为您提供内容为result的var {s: 123, t: 456},但也会执行您的函数中隐藏的任何代码。如果您从其他地方获取此输入,则代码可能正在执行,并且实际上并未破坏您的任何内容。现在是与JSON.parse

相同的示例
var result = JSON.parse(s);

它会在消息中抛出错误:

Uncaught SyntaxError: Unexpected token ( 

因此,即使有人试图将其隐藏起来,解析也会使您免于远程执行代码。

答案 4 :(得分:0)

eval不是表达式 - 我已经更新它以评估eval(s2 === s1); 否则它会尝试&执行eval&中的内容停止执行。

答案 5 :(得分:0)

eval()尝试评估一段JavaScript代码。如果您创建了一个以相同文本开头的脚本文件,则会出现相同的错误。在这种情况下,我认为大括号表示复合语句,如在if语句或for语句主体中,但在复合语句的开头是一个后跟冒号的字符串,这是无效的语法。

如果你想要一个能够评估一个对象的字符串,你必须将对象表达式括在括号中,以使它明确表示它是一个表达式。但正如apocalypz所说,你不应该试图评估JSON。在很多层面都是错的。

答案 6 :(得分:0)

如果你真的想要使用 eval 而不是 JSON.parse() 来解析JSON那么你应该写点东西像

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

...