扣子JavaScript代码块实现复杂数学公式解析与计算
在扣子(Coze)中处理复杂数学公式,核心痛点在于平台对原生JavaScript执行的限制。要让公式顺利运行,必须依赖其JavaScript代码块,同时结合严格的输入格式化和安全表达式校验。下面直接提供完整解决方案。
准备可计算的数学表达式输入
首先,在前序Bot节点中,通过「文本提取」或「变量赋值」将用户输入的公式转换为纯字符串变量。例如命名为formula_str,但必须提前规避以下陷阱:禁止包含中文括号、全角符号、变量定义语句(如let x = 1)、函数声明或console.log等非法内容。
接下来执行关键的安全检查:使用「条件判断」节点过滤危险字符。如果formula_str包含【eval、function、=>、{、}、import、require】中的任一字符串,立即终止流程并返回错误提示。
这一步不可省略。Coze的JS代码块底层虽采用QuickJS沙箱,但Function构造器未被禁用。简言之,【直接传入new Function(...)字符串,可能触发任意代码执行】,风险极高。
使用mathjs库进行安全解析与计算
获得安全输入的公式后,推荐两种计算路径。
方法一:调用内置mathjs(推荐)
直接在Ja vaScript代码块中粘贴以下代码:
const math = require('mathjs');
try {
const result = math.evaluate(formula_str);
output = { value: result };
} catch (e) {
output = { error: '计算失败:' + e.message };
}
特别说明:mathjs不仅支持加减乘除,还可处理矩阵运算、复数计算、导数(derivative)和积分(integral)等高级操作。例如输入integral(sin(x), x, 0, pi),将正确返回2。
方法二:手动白名单校验 + 基础运算(无依赖)
若无需引入外部库,可采用备选方案:仅允许数字、四则运算符、括号、点号、科学计数法e/E以及预设函数名(sin、cos、log、sqrt、pow)。核心逻辑通过正则进行白名单过滤:
const safePattern = /^[d+-*/().s^eEs]+|sin|cos|tan|log|ln|sqrt|abs|pi|e$/i;
if (!safePattern.test(formula_str)) { output = { error: '含不支持的符号' }; return; }
try {
const result = eval(formula_str.replace(/^/g, '**').replace(/pi/g, 'Math.PI').replace(/e/g, 'Math.E'));
output = { value: result };
} catch (e) {
output = { error: '语法错误' };
}
此方法轻量但功能有限,适用于简单数学运算。
处理多变量与上下文代入
公式常包含变量,如x^2 + 2*x + 1。需要提前在Bot流程中定义变量对象。
首先,创建JSON格式的变量映射:
const vars = { x: 3, y: 2.5, theta: 0.785 };
然后,在Ja vaScript代码块中使用mathjs的scope功能:
const math = require('mathjs');
try {
const scope = { ...vars };
const result = math.evaluate(formula_str, scope);
output = { value: result };
} catch (e) {
output = { error: e.message };
}
需注意,vars中的键名必须与公式中的变量名完全一致,大小写敏感,且不能使用保留字(如const、return)。
