【问题标题】:jQuery uses (new Function("return " + data))(); instead of eval(data); to parse JSON, why?jQuery 使用 (new Function("return " + data))();而不是 eval(data);解析 JSON,为什么?
【发布时间】:2010-03-15 17:46:18
【问题描述】:

This link 向您展示了 jQuery 使用 (new Function("return " + data))(); 用于旧版浏览器来解析 JSON 字符串而不是 eval()

这样做有什么好处?如果 JSON 字符串不安全怎么办?

【问题讨论】:

    标签: javascript jquery json


    【解决方案1】:

    尼克的回答中的引用暗示了这一点。其实差别不大,但感觉evalnew Function“差”。不是在安全性方面 — 它们在面对不受信任的输入时同样无用,但是希望您的 web 应用不会返回不受信任的 JSON 字符串 — 但是在语言级别的怪异方面,因此对优化的阻力。

    具体来说:

    function victim() {
        var a= 1;
        eval('a= 2');
        return a;
    }
    

    给出2evaled 字符串对victim 的局部变量作用域进行了操作!这是普通用户编写的函数永远无法做到的; eval只能这么做,因为它是黑魔法。

    使用常规函数代替了这个魔法元素:

    function victim() {
        var a= 1;
        (new Function('a= 2;'))();
        return a;
    }
    

    在上面,返回的a仍然是1;新函数只能对自己的局部变量或全局window.a进行操作。

    这些知识允许代码分析工具 — 可能包括 JavaScript 引擎和特别聪明的缩小器 — 应用更多优化。例如,第二个victim 函数可以将a 变量完全优化为return 1eval 的一种用法和许多潜在的优化是不可行的。

    当然,对于像 JSON eval​er 这样的小函数,在实践中不会有明显的区别,但总的来说,想法是:

    • 尽可能避免使用这两种方法(ECMAScript 第五版的严格模式中都不允许使用这两种方法);
    • 如果你必须使用一个,new Functioneval 更可取,除非你真的需要代码来访问调用函数的局部变量。

    【讨论】:

      【解决方案2】:

      至于为什么jQuery专门使用new Function()John Resig answered this on the jQuery forums

      使用 eval 会导致代码压缩器出现各种问题,因为不清楚在 eval 中可以执行什么。查看该运行的最后结果,看起来 new Function 与 eval 相当,有时甚至更快。一个例外是 Safari 4 - 但这些结果已经过时了,Safari 4 附带了我们使用的原生 JSON.parse 实现。

      【讨论】:

        【解决方案3】:

        http://www.json.org/js.html

        eval 函数非常快。但是,它可以编译和执行任何 JavaScript 程序,因此可能存在安全问题。 eval 在来源受信任和有能力 时被指示使用。 使用 JSON 解析器更安全。在基于 XMLHttpRequest 的 Web 应用程序中,只允许与提供该页面的同一源进行通信,因此它是受信任的。但它可能不能胜任。如果服务器的 JSON 编码不严格,或者它没有严格验证其所有输入,那么它可能会传递可能携带 危险脚本 的无效 JSON 文本。 eval 函数会执行脚本,释放其恶意。

        safe 到底是什么意思? 至少没有执行恶意代码;)

        另见:Alternatives to JavaScript eval() for parsing JSON

        另一点可能是,new Function() 被认为是 little faster 而不是 eval

        更新:

        您基本上可以在comments on jQuery's .parseJSON() function 中阅读相同的论点。

        【讨论】:

        • 这是一个好的答案吗? Luca 想知道evalnew Function(...) 有何不同,这只是说明eval 有什么问题。
        • @gabe:好吧,他并没有说他想知道这些差异。他想知道安全速度的好处。
        • Felix:Luca 想知道new Function()eval 更好。您回答 eval 是危险的,同时错误地暗示 new Function() 在某种程度上不那么危险。事实上,您的第二点(它更快)似乎是您答案中唯一正确的部分。
        • @gabe:实际上,第二部分似乎只适用于旧版本的 Firefox,但与其他浏览器的小缺陷相比,它是 Firefox 的重大改进 - weblogs.asp.net/yuanjian/archive/2009/03/22/…
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-01-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多