eval是一個被濫用得很嚴重的JavaScript特性。eval函數傳遞一個字符串給JavaScript編譯器,該字符串會被當成一段JavaScript程序來解析和執行。
很多開發者對JavaScript語言一知半解,卻喜歡使用eval。例如,如果只知道點表示法,卻不知道下標表示法,就會按如下方法編寫代碼:
eval("value=obj."+key+";");
而不是按如下方法編寫:
value=obj[key];
使用eval形式的代碼會更加難以閱讀。這種形式將使代碼性能顯著降低,因為eval必須運行編譯器,同時這種形式減弱了Web應用的安全性,因為它向被求值的文本授予了太多的權限。使用eval與使用with語句一樣,降低了語言的性能。
除了顯式調用eval外,JavaScript還支持隱式調用eval。Function構造器是eval的另一種形式,所以也應該避免使用它。當傳遞的是字符串參數時,setTimeout和setInterval函數(瀏覽器提供的函數,能接受字符串參數或函數參數)會像eval那樣去處理,因此也應該避免使用字符串參數形式。例如,下面是使用函數參數形式進行的處理。
var obj={
show1:function{
alert("時間到!");
},
show2:function{
alert("10秒一次的提醒!");
};
};
setTimeout(obj.show1,1000);
setTimeout("obj.show1;",2000);
setInterval(obj.show2,10000);
setInterval("obj.show2;",10000);
在Ajax應用中,JSON是一種流行的瀏覽器端與服務器端之間傳輸數據的格式。服務器端傳過來的數據在瀏覽器端通過JavaScript的eval方法轉換成可以直接使用的對象。然而,在瀏覽器端執行任意的JavaScript會帶來潛在的安全風險,惡意的JavaScript代碼可能會破壞應用。對於這個問題,有兩種解決方法:
❑帶註釋的JSON(JSON comments filtering)。
❑帶前綴的JSON(JSON prefixing)。
這兩種方法都是在Dojo中用來避免JSON劫持(JSON hijacking)的方法。帶註釋的JSON指的是從服務器端返回的JSON數據都是帶有註釋的,瀏覽器端的JavaScript代碼需要先去掉註釋的標記,再通過eval來獲得JSON數據。這種方法一度被廣泛使用,後來被證明並不安全,還會引入其他的安全漏洞。帶前綴的JSON是目前推薦使用的方法,這種方法的使用非常簡單,只需要在從服務器端返回的JSON字符串之前加上{}&&,再調用eval方法。關於這兩種方法的細節,可參考http://www.ibm.com/developerworks/cn/web/wa-lo-dojoajax1/?S_TACT=105AGX52&S_CMP=tec-csdn#resources中的內容。對JSON字符串進行語法檢查,安全的JSON應該是不包含賦值和方法調用的。在JSON的RFC 4627中,給出了判斷JSON字符串是否安全的方法,此方法通過兩個正則表達式來實現(代碼如下)。
var my_JSON_object=!(/[^,:{}\[\]0-9.\-+Eaeflnr-u\n\r\t]/.test(text.replace(/"(\\.|[^"\\])*"/g,'')))&&eval('('+text+')');