我需要在 Javascript 中评估用户输入的算术表达式,如“2 * (3 + 4)”,但出于安全原因,我不想使用 eval
。
我可以去掉所有不是数字或运算符的字符,但我不确定这是否安全,如果用户可以使用像 cos
, sqrt
这样的函数就好了 ---
等等…
有没有做算术表达式评估的 Javascript 库?
原文由 Giuseppe Ottaviano 发布,翻译遵循 CC BY-SA 4.0 许可协议
我需要在 Javascript 中评估用户输入的算术表达式,如“2 * (3 + 4)”,但出于安全原因,我不想使用 eval
。
我可以去掉所有不是数字或运算符的字符,但我不确定这是否安全,如果用户可以使用像 cos
, sqrt
这样的函数就好了 ---
等等…
有没有做算术表达式评估的 Javascript 库?
原文由 Giuseppe Ottaviano 发布,翻译遵循 CC BY-SA 4.0 许可协议
如前所述,任何用户可能造成的最大损害几乎就是他们已经可以使用任何主要浏览器中的内置控制台所做的事情。但是,如果您想限制用户使用 Math
属性/方法,您可以编写一个简单的正则表达式来为您处理这个问题。这样的事情应该有效:
function mathEval (exp) {
var reg = /(?:[a-z$_][a-z0-9$_]*)|(?:[;={}\[\]"'!&<>^\\?:])/ig,
valid = true;
// Detect valid JS identifier names and replace them
exp = exp.replace(reg, function ($0) {
// If the name is a direct member of Math, allow
if (Math.hasOwnProperty($0))
return "Math."+$0;
// Otherwise the expression is invalid
else
valid = false;
});
// Don't eval if our replace function flagged as invalid
if (!valid)
alert("Invalid arithmetic expression");
else
try { alert(eval(exp)); } catch (e) { alert("Invalid arithmetic expression"); };
}
我知道你不想使用 eval
出于安全原因,但正则表达式应该使它非常安全,因为它排除了任何不是 Math
对象的 直接 属性的单词和大多数非数学 JS 运算符,包括赋值运算符( =
)和二元运算符。更难的方法是编写分词器来解析数学表达式,因为它不是常规语言。
随意尝试打破我写的 工作示例,如果可以或者如果您发现问题,请发表评论,我会看看我能做些什么来解决它。
注意:Yi Jiang [在 JavaScript 聊天中](https://chat.stackoverflow.com/rooms/17/javascript) 提到,对于像 `Math.PI` 这样的东西允许小写可能也很有用。如果是这种情况,您可以在替换函数中添加以下“else if”语句:
else if (Math.hasOwnProperty($0.toUpperCase())
return "Math."+$0.toUpperCase();
在 if
和 else
语句之间添加它( 示例)。
原文由 Andy E 发布,翻译遵循 CC BY-SA 4.0 许可协议
13 回答12.8k 阅读
7 回答1.9k 阅读
3 回答1.1k 阅读✓ 已解决
2 回答1.2k 阅读✓ 已解决
6 回答872 阅读✓ 已解决
6 回答1k 阅读
2 回答1.3k 阅读✓ 已解决
您可以尝试 JavaScript Expression Evaluator :
那么你的代码将是这样的:
源代码位于 GitHub 上,并在 npm 上发布为
expr-eval
。可以这样使用: