Possible Duplicate:
Safe evaluation of arithmetic expressions in Javascript
我正在尝试构建一个在线计算器,作为我一直在做的网站的一部分。
我有 + - */( ) AVG MIN MAX sine cos etc
作为操作。有用于数字、运算符和功能的按钮。我只是在按下任何按钮后附加一个字符串。
我必须在 UI 端构建一个基本的语法检查器。服务器将实际执行操作并将它们存储并显示。我不想花太多时间编写客户端代码,但我的想法是验证它在数学上是否有意义。
这是我的计划:
我将尝试对生成的字符串执行 eval()
并捕获错误。如果错误是 synatxError,那么这意味着该字符串在语法上是错误的。如果是任何其他类型的错误,我都可以接受。
所以我在脚本的开头这样做了:
Error.prototype.dummy_attribute = "notSyntaxError"
SyntaxError.prototype.dummy_attribute = "SyntaxError"
上述方法对我来说效果不佳,因为如果有字符串链接 2()
我会收到类型错误。现在我必须编写一个代码来检查空括号和前面没有运算符的括号,或者后面没有运算符的括号
或者是否有一种替代方法可以用来检查字符串的语法,我必须看看它在数学上是否有意义。
eval 是可能的。我知道一些顽固的 eval 仇恨者会对此投反对票。唯一不好的方法是让人们在查询字符串中使用等式提供指向您页面的链接。这将使您容易受到 XSS 攻击。如果您仅在当前页面上使用它进行验证,那么这个人只会搞砸自己的页面,不会给其他人带来风险。
基本思路:
function avg () {
var len = arguments.length;
if(len===0) {
throw "no arguments suppulied for AVG";
}
var arr = Array.prototype.slice.call(arguments, 0);
var total = 0;
for (var i=0; i<len; i++) {
total += arr[i];
}
return total/len;
}
function sine (num) {
return Math.sin(num);
}
function max () {
var len = arguments.length;
if(len===0) {
throw "no arguments suppulied for MAX";
}
var arr = Array.prototype.slice.call(arguments, 0);
return Math.max.apply(null, arr);
}
function isValidEqn (eqn) {
try{
eval("var x = " + eqn.toLowerCase());
return !isNaN(x);
} catch(e) {
//console.error(e);
return false;
}
}
var eqn1 = "AVG ( 2008 , 2000 )";
var eqn2 = "AVG ( 2008 , 2000 ) / 100 + sine(10)";
var eqn3 = "AVG ( 2008 , 2000 ) / 100 + sine(10) + MAX(10,20)";
console.log("sadjhsahd", isValidEqn("sadjhsahd") );
console.log(eqn1, isValidEqn(eqn1) );
console.log(eqn2, isValidEqn(eqn2) );
console.log(eqn3, isValidEqn(eqn3) );