我正在开发一个 Web 应用程序,管理员可以在其中定义和调整需要根据最终用户提供的输入值(数字)进行评估的公式。
为了清楚起见,以下是我要排除的简化示例:
const obj = {
type: "External wall in contact with the ground",
layer: {
base: {
type: "Reinforced concrete (reinforcement 5 vol.%)",
thickness: 100, // <-- user value
lambda: 2.3, // <-- user value
_r: "{{thickness}}/{{lambda}}/1000", // <-- admin defined
r: 0
},
waterproofing: {
type: "Bitumen sheets (single layer)",
share: 1, // <-- user value
_r: "{{share}}", // <-- admin defined
r: 0,
},
insulation: {
type: "XPS",
thickness: 100, // <-- user value
share: 1, // <-- user value
lambda: 0.040, // <-- user value
_r: "{{thickness}}*{{share}}/{{lambda}}/1000", // <-- admin defined
r: 0
}
}
}
Object.entries(obj.layer).forEach(([key, object]) => {
var formula = object._r
Object.keys(object).forEach(k =>
formula = formula.replace(`{{${k}}}`, object[k])
)
obj.layer[key].r = eval(formula)
})
console.log(obj)
这_r是管理员定义的公式。这些{{value}}是最终用户提供的值。
该循环遍历obj.layer属性来评估公式并将答案保存在 中r。
结果将是这个对象:
{
type: 'External wall in contact with the ground',
layer: {
base: {
type: 'Reinforced concrete (reinforcement 5 vol.%)',
thickness: 100,
lambda: 2.3,
_r: '{{thickness}}/{{lambda}}/1000',
r: 0.043478260869565216
},
waterproofing: {
type: 'Bitumen sheets (single layer)',
share: 1,
_r: '{{share}}',
r: 1
},
让我们跳过我不验证对象结构并确保所有值都可用的事实。
我知道eval()
这被认为是“危险的”。一个不太好的选择是Function()
。然而,并不完美。
到目前为止,我看到了 3 种可能性:
只有管理员可以更改公式。因此,执行恶意代码的风险非常低。我需要的是验证/清理这些值(类似isFloat()
),仅此而已。
使用该mathjs
库,它提供了一个很好的evaluate()
功能:
繁华开满天机
相关分类