2012-12-03 85 views
2

我還是給JavaScript很新(不編碼雖然),可以隨意挑剔和白癡地圖的事情對我來說。Javascript - eval對象創建?

我試圖創造的東西,將接受用戶的輸入。如果第一個字符是感嘆號,它會嘗試創建一個具有該名稱的對象並運行該對象的「操作」方法。否則它會像對待普通的文本(現在警報)

<script type="text/javascript"> 
function GetInput(input){ 

    // Trim the spaces off the beginning and end 
    input = input.trim(); 

    if(input.charAt(0) != "!"){ 
     // Just some normal text 
     alert(input); 

     return true; 
    } 

/* Cut off the exclamation point, replace multiple spaces with one, 
* and get the arguments if any. args[0] = the command. */ 

    var args = input.substr(1).replace(/\s{2,}/g, " ").split(" "); 

// Make sure the function is an object with a method named "action" 
    if(eval("typeof "+args[0]+";") === "function" 
     && eval("typeof "+args[0]+".prototype.action;") === "function"){ 

     eval("var command = new "+args[0]+"();"); 

     command.action(args); 
    }else{ 
     alert('"'+args[0]+'" is not a command.'); 
    } 

    return true; 
} 
</script> 

我這個至今注意到唯一的問題是eval語句。我知道我可以使用一個開關/箱和溝EVAL都在一起,甚至使含允許的功能名稱的數組和之前的eval比較數組的輸入,但我敢肯定,我們有了一個更好的辦法。

我只是希望能夠使對象和方法,而不是更新任何東西(我相信是的鴨打字的主要用途之一?)。這可能沒有eval?如果沒有,有沒有一種簡單的方法來淨化輸入字符串,以避免像「!eval(alert('u b haxed'))」或「!a;alert('u b haxed')」?

在此先感謝

+0

的可能重複(HTTP [javascript中的動態物體建設?]://計算器的.com /問題/ 3871731 /動態對象的施工中的JavaScript) – zerkms

回答

2

你應該使用eval只有一次獲得的功能,然後用它做的一切在一個變量。

var args = input.substr(1).split(/\s+/); 
var fn = eval(args[0]); 
if (typeof fn == 'function' && typeof fn.prototype.action == 'function') { 
    var command = new fn(); 
    command.action(args); 
} else { 
    alert('"'+args[0]+'" could not be evaluated to a valid command.'); 
} 

return true; 

如果這些構造函數是全局變量,也可以訪問他們的window對象的屬性:

var fn = window[ args[0] ]; 
+0

不宜用'eval'甚至一次作爲'ARGS [0]'來自用戶的輸入。 'windows [args [0]]'更安全。 – TwiNight

+0

在這個答案和TwiNight的評論之間,我得到了我需要的東西。非常感謝你。 –

+0

@TwiNight:並非一般,因爲每個用戶都可以在自己的瀏覽器中手動執行惡意代碼。 'window [args [0]]'不會有任何副作用,但更受限制。取決於用戶的需求以及他的經驗。 – Bergi