繁体   English   中英

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

[英]Difference between JSON.parse() and eval()

这个可能需要一个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 在这里

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

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

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

JSON和JavaScript对象有什么区别?

$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

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

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

的jsfiddle

查看规范中有关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);

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

var result = JSON.parse(s);

它会抛出错误消息:

Uncaught SyntaxError: Unexpected token ( 

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

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

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

如果您想要一个可以计算对象的字符串,则必须将对象表达式括在括号中,以使其明确表示它是一个表达式。 但正如apocalypz所说,你不应该试图评估JSON。 这么多级别都是错的。

如果你真的想使用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 :)

...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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