简体   繁体   English

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

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

May need a Javascript language lawyer for this one: 这个可能需要一个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")

eval fails on s1 , s2 , and "("+s2+")" . evals1s2"("+s2+")"上失败。

jsFiddle here . jsFiddle 在这里

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

JSON.parse() function is for parse JSON string. JSON.parse()函数用于解析JSON字符串。 Although very simmilar, do not make mistake, JSON is not Javascript and there are tiny differences. 虽然非常相似,但不要弄错,JSON不是Javascript并且存在微小的差异。 You should not use eval() for parsing JSON 您不应该使用 eval()来解析JSON

What are the differences between JSON and JavaScript object? JSON和JavaScript对象有什么区别?

$eval is automatically evaluated against a given scope. $eval会根据给定范围自动评估。

For example: 例如:

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

$parse does not require scope. $parse不需要范围。 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解析JSON时,您需要用括号包装表达式

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

jsfiddle 的jsfiddle

Check out what the specification says about JSON and eval http://www.json.org/js.html Notice this part specifically 查看规范中有关JSON和eval的内容http://www.json.org/js.html请特别注意这一部分

The eval function is very fast. eval功能非常快。 However, it can compile and execute any JavaScript program, so there can be security issues. 但是,它可以编译和执行任何JavaScript程序,因此可能存在安全问题。 The use of eval is indicated when the source is trusted and competent. 当源是可信的并且胜任时,指示使用eval。 It is much safer to use a JSON parser. 使用JSON解析器更安全。 In web applications over XMLHttpRequest, communication is permitted only to the same origin that provide that page, so it is trusted. 在基于XMLHttpRequest的Web应用程序中,只允许与提供该页面的同一源进行通信,因此它是可信的。 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. 如果服务器的JSON编码不严格,或者它没有严格验证其所有输入,那么它可能会传送可能带有危险脚本的无效JSON文本。 The eval function would execute the script, unleashing its malice. eval函数将执行脚本,释放其恶意。

JSON is just a javascript object, and nothing more. JSON只是一个javascript对象,仅此而已。 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. 有效的javascript可能包括函数,执行块等。如果你只是eval()一个字符串,它可能有代码。如果它只是JSON,JSON将解析,但你不能确定只是将它填入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. 会给你一个内容{s: 123, t: 456}的var result ,但也会执行你函数中隐藏的任何代码。 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 现在与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); eval不是表达式 - 我已经更新它以评估eval(s2 === s1); Otherwise it will try & execute what's within the eval & stop execution. 否则它将尝试执行eval中的内容并停止执行。

eval() attempts to evaluate a block of JavaScript code. eval()尝试评估一段JavaScript代码。 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语句或for语句主体中,但在复合语句的开头是一个后跟冒号的字符串,这是无效的语法。

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. 但正如apocalypz所说,你不应该试图评估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 如果你真的想使用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