eval函数是一种强大而简单的动态生成代码的方法,那么有什么注意事项呢?
当前回答
这大大降低了您对安全性的信心。
其他回答
我想到两点:
安全性(但只要您自己生成要计算的字符串,这可能就不是问题) 性能:除非要执行的代码是未知的,否则无法进行优化。(关于javascript和性能,当然是Steve Yegge的演示)
将用户输入传递给eval()存在安全风险,而且每次调用eval()都会创建一个JavaScript解释器的新实例。这可能会占用资源。
我想说的是,如果你在javascript中使用eval()并不重要,因为它是在浏览器中运行的。
所有现代浏览器都有一个开发者控制台,在那里你可以执行任意的javascript,任何半聪明的开发者都可以查看你的JS源代码,并将他们需要的任何部分放入开发控制台来做他们想做的事情。
*只要你的服务器端对用户提供的值进行了正确的验证和消毒,在你的客户端javascript中解析和评估什么都不重要。
然而,如果你问在PHP中是否适合使用eval(),答案是否定的,除非你将任何可能传递给eval语句的值列入白名单。
除非您100%确定正在评估的代码来自可信的来源(通常是您自己的应用程序),否则这将使您的系统暴露于跨站点脚本攻击。
这并不总是一个坏主意。以代码生成为例。我最近写了一个叫做Hyperbars的库,它在虚拟世界和把手之间架起了桥梁。它通过解析句柄模板并将其转换为虚拟dom使用的超脚本来实现这一点。超脚本首先作为字符串生成,在返回它之前,eval()将其转换为可执行代码。我发现eval()在这种特殊情况下与邪恶完全相反。
基本上从
<div>
{{#each names}}
<span>{{this}}</span>
{{/each}}
</div>
这个
(function (state) {
var Runtime = Hyperbars.Runtime;
var context = state;
return h('div', {}, [Runtime.each(context['names'], context, function (context, parent, options) {
return [h('span', {}, [options['@index'], context])]
})])
}.bind({}))
eval()的性能在这种情况下不是问题,因为您只需要解释一次生成的字符串,然后多次重用可执行输出。
如果您好奇的话,您可以看到代码生成是如何实现的。