天天看點

JavaScript中eval()和$.parseJSON()的差別和聯系以及JSON.stringify()的差別

JavaScript中eval()和$.parseJSON()的差別和聯系以及JSON.stringify()的差別

一、第一個差別是:安全性

json格式非常受歡迎,而解析json的方式通常用JSON.parse()但是eval()方法也可以解析,這兩者之間有什麼差別呢?JSON.parse()之可以解析json格式的資料,并且會對要解析的字元串進行格式檢查,如果格式不正确則不進行解析,而eval()則可以解析任何字元串,eval是不安全的

var str = 'alert(1000.toString())';
eval(str);
JSON.parse(str);      

用eval可以解析,并且會彈出對話框,而用JSON.parse()則解析不了。 其實alert并沒有什麼壞處,可怕的是如果用惡意使用者在json字元串中注入了向頁面插入木馬連結的腳本,用eval也是可以操作的,而用JSON.parse()則不必擔心這個問題。

注意:某些低級的浏覽器尚不支援JSON.parse() 《高性能Javascript》一書即指出:警告:關于JSON和eval需要注意的是:在代碼中使用eval是很危險的,特别是用它執行第三方的JSON資料(其中可能包含惡意代碼)時,盡可能使用JSON.parse()方法解析字元串本身。該方法可以捕捉JSON中的文法錯誤,并允許你傳入一個函數,用來過濾或轉換解析結果。如果此方法以備Firfox 3.5 、IE8 及 Safari 4 原生支援。大多數javascript類庫包含的JSON解析代碼會直接調用原生版本,如果沒有原生支援的話,會調用一個略微不那麼強大的非原生版本來處理。

二、 第二個差別:JSON.parse()解析的必須是json格式的字元串要不報錯,而eval()則沒有這麼嚴格

在這裡“json格式的字元串”是指要求指定的字元串必須符合嚴格的JSON格式,例如:屬性名稱必須加雙引号、字元串值也必須用雙引号。

如果傳入一個格式不"完好"的JSON字元串将抛出一個JS異常 json的解析方法共有兩種:eval 和 JSON.parse(),如:

var jsonStr= '{"name":"lulu", "sex":"female"}';
var evalJson=eval('('+jsonStr+')');
var jsonParseJson=JSON.parse(jsonStr);      

這樣就把json格式的字元串jsonStr轉換成了JSON對象。

但是差別是:

var age = 27;
var jsonStr= '{"name":"lulu", "sex":"female","age":++age}';
var evalJson=eval('('+jsonStr+')'); //不報錯此時age的值是28
var jsonParseJson=JSON.parse(jsonStr);//報錯      

從上面eval()函數的用法我們可以看出eval()函數在解析json格式的字元串時要加上圓括号如eval(’(’+jsonStr+’)’),這是因為:eval本身的問題。 由于json是以”{}”的方式來開始以及結束的,在JS中,它會被當成一個語句塊來處理,是以必須強制性的将它轉換成一種表達式。

加上圓括号的目的是迫使eval函數在處理JavaScript代碼的時候強制将括号内的表達式(expression)轉化為對象,而不是作為語句(statement)來執行。舉一個例子,例如對象字面量{},如若不加外層的括号,那麼eval會将大括号識别為JavaScript代碼塊的開始和結束标記,那麼{}将會被認為是執行了一句空語句。

三、JSON.stringify()

var jsonObj = {"name":"lulu","sex":"female"};
var jsonStr = JSON.stringify(jsonObj);      

繼續閱讀