Eval 函数是种行之有效的方法来动态生成的代码中,那么是什么忠告?

2008-09-17 19:09:54
问题评论:

不能因为 eval () 由 Simon Willison- 24ways.org/2005/dont-be-eval

Moduscreate.com/javascript 的性能-技巧的技巧-中所述 (新 Function(str))() 的比 eval(str) 更多性能。只是我 2 美分:)

新的 fcuntion(a) 显然是 67%低于 eval(a) 在 chrome 上

我的新 functions(a) 是 80%慢最新 chrome 在 osx 上

添加静态函数,只是为了性能进行比较。jsperf.com/eval-vs-new-function/2

回答:

  1. 不当使用 eval 打开代码注入式攻击

  2. 调试可更具挑战性 (没有行号) 等。

  3. 评估者的代码执行速度更慢 (没有机会编译/缓存 eval 有代码)

编辑︰ @Jeff Walden 在评论中指出,3 是不尽然今天超过了 2008 年。但是,尽管某些缓存的已编译的脚本,则可能出现这将只是限于脚本 eval 有重复在不修改。更可能的情况是,您 eval'ing 脚本,都经历了稍作修改,每次这种情况下不能缓存。我们只能说,有些评估获得的代码执行速度更慢。

@JeffWalden,很好的注释。我已经更新张贴内容,尽管我意识到自从您过账,已经一年。Xnzo72,如果您有资格评论有些 (如李明做的那样) 然后我也许能够同意您的。Jeff 指出的关键:"eval 同一字符串的多个时间可以避免分析系统开销"。由于它是,不只是错误消息。3 对于许多情况下如此。

@Prestaul︰ 由于假定的攻击者就可以使用任何开发人员工具来更改客户端 JavaScript,为什么不要您说因为 eval () 打开您的代码注入攻击?不是已经打开了吗?(我所讲述的关于客户端 JavaScript 当然)

@EduardoMolteni,我们不介意 (和确实无法阻止) 用户在他们自己的浏览器中执行 js。将用户提供的值获取保存,然后稍后放置到 javascript,eval 时我们试图避免攻击。例如,我可以将我的用户名设置为︰ badHackerGuy'); doMaliciousThings();如果您采取我的用户名连接到某些脚本并评估它在浏览器中其他人然后我可以在他们的计算机上运行任何我想要的 javascript (例如强制它们为 + 1 我的帖子,其将数据发送到我的服务器,等等。)

一般情况下,#1 适用于很多,如果不是大多数的函数调用。不应意见和经验丰富的程序员,只是因为经验不足的程序员滥用其避免因为 eval ()。但是,经验丰富的程序员通常具有更好的体系结构,在他们的代码,并且因为 eval () 很少会需要甚至思想有关由于此更好的体系结构。

@TamilVendhan 确保您可以放置断点。您可以访问虚拟文件为您 evaled 编码通过将debugger;语句添加到源代码中创建的镶边。这会在该行停止程序的执行。再之后,您可以添加调试断点,它是只是另一个 JS 文件等。

评估并不总是邪恶。是时候是完全合适。

但是,评估当前和历史上大规模过度使用人不知道自己在做什么。遗憾的是,其中包括编写 JavaScript 教程的人,在某些情况下这可以确实拥有安全后果-或更通常情况下,简单的 bug。那么多我们怎样才能引发问号转移 eval,效果就越好。使用 eval 任何时候需要健全性的检查自己要做什么,因为很有可能您可做它更好,更安全,更干净的方式。

若要使所有过的典型示例,来设置元素的颜色 id 存储在变量马铃薯:

eval('document.' + potato + '.style.color = "red"');

如果上面的代码的那种作者没有线索如何 JavaScript 对象工作的基本知识,他们会有 realised 方括号可以代替文本点的名称,因而需要评估︰

document[potato].style.color = 'red';

...which 将更易读和更少可能错误。

(然后,/really/ 知道他们在做什么的人会说,但是︰

document.getElementById(potato).style.color = 'red';

这是比 dodgy 的访问 DOM 元素从文档对象垂直旧技巧更可靠。

嗯,猜猜我第一次学习 JavaScript 时,我是幸运的。我总是使用"document.getElementById"来访问 DOM 中;篇幅有限,我只做了它在时间因为我没有一个线索如何对象从事 JavaScript;-)

同意。有时 eval 是例如来自 web 服务的 JSON 响应 ok

@schoetbi︰ 不应该使用JSON.parse()而不是eval()为 JSON 吗?

@bobince code.google.com/p/json-sans-eval适用于所有的浏览器,因此没有github.com/douglascrockford/JSON-js在内部,但检查,Doug Crockford json2.js 不使用 eval。此外,它的向前兼容使用 JSON 的内置浏览器支持。

有 @bobince 是东西称为的特征检测和 polyfills 处理缺少的 JSON 库和其他的事情 (看modernizr.com)

我相信这是因为它可以从一个字符串执行任何 JavaScript 函数。使用它可使人们将恶意代码插入到应用程序更容易。

然后是另一种什么?

真正的替代方法是只需编写代码并不需要它。Crockford 进入长度有关,和如果您需要使用它,他基本上说,它是程序设计缺陷,并需要进行返工。说实话,我同意他太。所有它的缺陷是非常灵活,并允许很大的空间,使其更灵活的 JS。

事实并非如此,大多数框架有一个方法来解析 JSON,并且如果您不使用一个框架,您可以使用 JSON.parse ()。大多数浏览器都支持它,并且如果你真的在必要,您可以编写一个分析器为 JSON 很轻易地。

我不要购买此参数,因为它已经可以很容易地将恶意代码插入到一个 Javascript 应用程序。我们有浏览器控制台和脚本扩展等...每一段代码向客户端发送的是可选的客户端来执行。

点是,具有便于我将代码插入到您的浏览器。让我们假设您使用 eval 查询字符串上。如果我诱使您单击链接转到该网站与我连接的查询字符串,我现在已经从浏览器的完整权限的计算机上执行我的代码。我要键记录的所有内容键入网站并将其发送给我吗?完成的并不能停止我因为 eval 执行时,浏览器为其提供了最高权力机构。

想到的有两点︰

  1. 安全性 (但只要生成要计算您自己的字符串,这可能是一个非问题)

  2. 性能︰ 之前要执行的代码是未知的它不能进行优化。(关于 javascript 和性能,当然Steve Yegge 的演示文稿)

为什么安全是一个问题,如果客户端仍然可以做到我们的代码与任何她想吗?Greasemonkey 吗?

@PaulBrewczynski,安全问题将出现时用户 A 保存代码以将其部分eval削减,然后,那个小的代码运行在用户 B 浏览器

将传递到因为 eval () 的用户输入安全风险,但也因为 eval () 每次调用创建 JavaScript 解释器的新实例。这可以是资源扰乱。

在 3 年以上的工作因为我回答,我对所发生情况的了解,让我们说,deepened。实际情况是在创建一个新的执行上下文。请参见dmitrysoshnikov.com/ecmascript/chapter-1-execution-contexts

请输入您的翻译

Why is using the JavaScript eval function a bad idea?

确认取消