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()的性能在这种情况下不是问题,因为您只需要解释一次生成的字符串,然后多次重用可执行输出。

如果您好奇的话,您可以看到代码生成是如何实现的。