簡體   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