Eval功能是一个强大和简单的方法来动态产生的代码,那么什么是警告?

有帮助吗?

解决方案

  1. 不当使用 eval 打开了你 代码,用于注入攻击

  2. 调试 可以更加具有挑战性 (无线数,等等)。

  3. eval会代码的执行速度较慢(没有机会为编译/cache eval会代码)

编辑:作为@杰夫*瓦尔登指出,在评论意见,#3是不真实的今天于它是在2008年。然而,虽然有些缓存的编剧本可能发生这将只限于脚本eval会重复,没有修改。更可能的情况是,你是eval清脚本经历了微小的修改,每次为这样就不可能缓存。我们只能说,一些eval会代码的执行更加缓慢。

其他提示

eval并不总是邪恶的。有时候,这是完全适当的。

然而,eval是目前和历史上大规模过度使用人不知道他们在做什么。这包括人员编写JavaScript教程,不幸的是,在某些情况下,这可能确实已经安全后果--或者更经常的、简单的错误。所以我们可以做到扔的一个问题mark过eval,更好。任何时间使用eval你需要的理智-检查你在做什么,因为机会你可以做一个更好的、更安全、更清洁的方式。

得到一个所有太典型的例子中,设置的颜色一个元件和身份证件存在可变的'土豆':

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

如果提交人的代码,上面有一个线索的基本知识如何JavaScript对象的工作,他们必须意识到,方括号内,可以用来替代文字的点名称,不需要eval:

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

...这是更容易阅读,以及少潜在的越野车。

(但是,有人/真/知道他们在做什么会说:

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

这是更可靠狡猾的老把戏的访问DOM要素的文件的对象。)

我相信这是因为它可以执行的任何JavaScript能从一串。使用这使得人们更容易注入流氓码进入的应用程序。

两点我想到:

  1. 安全(但只要您产生串要评估自己,这可能是一个非问题)

  2. 性能:直到码要执行的是未知的,它不能进行最优化。(关于javascript和性能,当然 史蒂夫Yegge的演讲)

通过用户输入的到eval()是一个安全风险,而且每个用eval()创建一个新的实例JavaScript的解释。这可能是一个资源猪。

它一般只有一个问题,如果你穿eval用户输入。

主要是,它是很难保持和调试。它就像一个 goto.你可以用它,但是它使得它很难找到问题和困难的人可能需要更改后。

一件事,要记住的是,你可以经常使用eval()执行代码在另一个有限制的环境--社会网站这一块的具体JavaScript功能有时可以愚弄破它们在一个eval块

eval('al' + 'er' + 't(\'' + 'hi there!' + '\')');

所以如果你想要运行一些JavaScript code它在哪里否则可能不会被允许(Myspace, 我看你...)然后eval()可以成为一个有用的伎俩。

然而,对于所有上述原因,你不应该用你自己的代码,在那里,你有完全的控制-它只是不必要的,较好的降到'棘手的JavaScript黑客'架。

除非你让eval()一个动态的内容(通过cgi或输入),这是因为安全和坚实的所有其他JavaScript在你的网页。

随着其余的答案,我不认为eval的发言可以拥有先进的最小化。

这是一个可能的安全风险,它有一个不同范围的执行,并且是相当低效率的,因为它创建了一个全新的脚本环境中执行的代码。在这里看到一些更多的信息: eval.

这是很有用的,虽然和用有节制可以添加了很多良好的功能。

除非你是100%肯定的,该代码被评估的是从可信来源(通常为你自己的应用程序)然后这是一个正确的方式的暴露你的系统的交叉网站脚本的攻击。

我知道这次讨论是旧的,但是我真的很喜欢 办法通过谷歌并想分享这种感觉与其他人;)

其他的事情是,更好的,你得到更多的尝试理解和最后你就是不相信的东西是好的或坏的只是因为有人这么说:) 这是一个非常鼓舞人心 视频 帮我多想过我自己)的良好做法是好的,但不要使用他们mindelessly:)

这并不一定是坏提供你知道什么情况下你使用它。

如果应用程序的使用 eval() 创建一个对象从一些JSON其中有来自一个 程序 你自己的网站,创建信任的服务器方代码,也可能不是一个问题。

不信任的客户端JavaScript code不能做那么多呢。提供的东西你执行 eval() 在来自一个合理的来源,你的罚款。

它大大降低了你的水平的信心有关的安全。

如果你想要的用户可以输入一些逻辑职能和评估以及然后或JavaScript eval功能是完美的。我可以接受两个字符串 eval(uate) string1 === string2, 等等。

如果你发现使用eval()在代码中,记得的口头禅"eval()是邪恶的。"

此 功能需要的任意字符串并执行它作为JavaScript code.当代码中 问题是已知的预先(不确定的运行时),没有理由使用 eval().如果代码是动态产生的,在运行时,通常是一种更好的方式 实现这一目标没有eval().例如,仅仅使用方括号, 访问的动态属性是更好的和更简单:

// antipattern
var property = "name";
alert(eval("obj." + property));

// preferred
var property = "name";
alert(obj[property]);

使用 eval() 还有安全影响,因为你可执行代码(针对 例如,来自该网络)是已经被篡改。这是一个共同的反模式在处理JSON响应从阿贾克斯的请求。在这些情况下 这是更好地使用浏览器的内置的方法来分析id反应 确保它的安全和有效的。浏览器,不支持 JSON.parse() 本,你可以 使用一个图书馆从JSON.org.

同样重要的是要记住,通过字符串 setInterval(), setTimeout(), 和 Function() 构造是,大部分,类似于使用 eval() 因此 应该避免。

幕后,JavaScript仍然要评估和执行 字符串通作为编程代码:

// antipatterns
setTimeout("myFunc()", 1000);
setTimeout("myFunc(1, 2, 3)", 1000);

// preferred
setTimeout(myFunc, 1000);
setTimeout(function () {
myFunc(1, 2, 3);
}, 1000);

使用新的功能()构造相似eval()以及应接触 与照顾。这可能是一个强大的构造,但是经常被滥用。如果你绝对必须 使用 eval(), 你可以考虑采用新功能()instead.

有一个小的潜力 受益,因为该码进行评价在新的功能()将运行在当地的功能 范围,因此任何变量的定义与var在代码中被评估将不会成为 globals动。

另一种方法,以防止自动globals是包裹 eval() 调入一个立即的功能。

除了可能的安全问题,如果你正在执行的用户-提交了代码,大多数时间有一个更好的办法,不涉及重新解析代码每次它的执行。匿名的功能或目的性质可以更换大多数用途的eval和更安全,速度更快。

这可能成为更大的问题为下一代的浏览器来一些风味的JavaScript编译器。代码的执行通过Eval可以不执行,以及其他JavaScript对这些较新的浏览器。有人应该做一些分析。

这是一个很好的文章谈eval和如何它不是一个邪恶:http://www.nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderstood/

我不是说你应该去运行,并开始使用eval() 无处不在。事实上,很少有良好的使用情况对于运行 eval()。肯定有问题码清楚起见, debugability,并肯定性,不应该被忽视。但你不应该害怕去使用它的时候你有一个情况下 eval()有意义的。尽量不用它,但不要让任何人吓跑 你以为你的代码被更脆弱或较不安全的时候eval() 使用适当。

eval()非常强大的和可以被用来执行一个JS发言或评估的一种表达。但问题不是有关使用的eval()但是,让我们只是说了一些如何字符串中的运行与eval()受到恶意的一方。在结束你就可运行的恶意代码。与动力来重大的责任。所以明智地使用它,是你们使用它。这是不相关的多eval()function但是这篇文章有很好的信息: http://blogs.popart.com/2009/07/javascript-injection-attacks/ 如果你是在寻找的基本知识eval()看看这里:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval

我不会试图驳斥任何东西所说的迄今为止,但我会提供这种使用的eval(),(就我所知道的)不能做任何其他方式。有可能是其它方式代码这一点,并可能方法来优化它,但是,这样做是手写的,没有任何花俏为了清楚说明使用的eval,真的没有任何其他替代品。这是:动力(或者更准确地)programmically创建的目的名称(如相对值)。

//Place this in a common/global JS lib:
var NS = function(namespace){
    var namespaceParts = String(namespace).split(".");
    var namespaceToTest = "";
    for(var i = 0; i < namespaceParts.length; i++){
        if(i === 0){
            namespaceToTest = namespaceParts[i];
        }
        else{
            namespaceToTest = namespaceToTest + "." + namespaceParts[i];
        }

        if(eval('typeof ' + namespaceToTest) === "undefined"){
            eval(namespaceToTest + ' = {}');
        }
    }
    return eval(namespace);
}


//Then, use this in your class definition libs:
NS('Root.Namespace').Class = function(settings){
  //Class constructor code here
}
//some generic method:
Root.Namespace.Class.prototype.Method = function(args){
    //Code goes here
    //this.MyOtherMethod("foo"));  // => "foo"
    return true;
}


//Then, in your applications, use this to instantiate an instance of your class:
var anInstanceOfClass = new Root.Namespace.Class(settings);

编辑:顺便说一下,我不会建议(对所有的安全原因,指出迄今为止)基您对象名称上用户输入。我不能想象任何良好的原因,你就想这样做,虽然。是,我想它指出,它不会是一个好主意:)

JavaScript引擎有一定数量的绩效优化,它执行期间的编制阶段。这些都归结到能够基本上是静态分析代码,因为它lexes,并预先确定所有可变和功能的声明,因此,它需要较少的努力来解决标识期间执行的。

但是,如果发动机发现一个eval(..)在代码,它本质上有假设所有其认识,标识的位置可能是无效的,因为它不知道在各处的时间正好是什么代码你可以穿eval(..)修改词汇范围或内容的对象可以通过以用来创建一个新的词汇范围进行协商。

换句话说,在悲观意义上,那些最优化,它将是毫无意义的,如果eval(..)是存在的,所以它根本没有执行优化。

这就解释了这一切。

参考:

https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20&%20closures/ch2.md#eval

https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20&%20closures/ch2.md#performance

它并不总是一个坏主意。举个例子,代码生成。我最近写了一个图书馆叫 Hyperbars 这座桥梁之间的间隙 虚拟dom把手.它通过分析的一把手的模板和转换到它 hyperscript 这是随后使用通过虚拟dom。该hyperscript生成为一串的第一和返回之前, 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() 不是一个问题,在这样的情况,因为你只需要来解释产生串一次,然后再使用的可执行输出许多倍。

你可以看到代码生成的,是实现,如果你是好奇 在这里,.

我会尽说,它并不真正的问题,如果你使用 eval() 在javascript是在浏览器。*(警告)

所有现代浏览器拥有开发人员的控制台那里你可以执行的任意javascript无论如何,任何半聪明的开发者可以看看你的JS源和把任何位,它们需要进入开发控制台,要做到什么,他们的愿望。

*只要你的服务器的端点的正确验证和清洁的用户提供的价值,它应不论什么得到分析和eval会在你的客户的侧javascript。

如果你们要问,如果它适用 eval() 在PHP然而,答案是 没有, 除非你 白名单 任何价值可能会传递到你eval发言。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top