最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - jQuery uses (new Function("return " + data))(); instead of eval(data); to parse JSON, why? - Stac

programmeradmin9浏览0评论

This link shows you that jQuery uses (new Function("return " + data))(); for older browsers, to parse a JSON string instead of eval().

What are the benefits of this? What if the JSON string isn't safe?

This link shows you that jQuery uses (new Function("return " + data))(); for older browsers, to parse a JSON string instead of eval().

What are the benefits of this? What if the JSON string isn't safe?

Share Improve this question asked Mar 15, 2010 at 17:46 Luca MatteisLuca Matteis 29.3k22 gold badges116 silver badges171 bronze badges 0
Add a comment  | 

3 Answers 3

Reset to default 32

The quote in Nick's answer hints at it. It's not really a big difference, but the feeling is that eval is ‘worse’ than new Function. Not in terms of security — they're both equally useless in the face of untrusted input, but then hopefully your webapp is not returning untrusted JSON strings — but in terms of language-level weirdness, and hence resistance to optimisation.

Specifically:

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

gives 2. The eval​ed string has operated on victim's local variable scope! This is something that a regular user-written function could never do; eval can only do it because it is dark magic.

Using a regular function instead takes away this element of magic:

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

in the above, the returned a remains 1; the new Function can only operate on its own local variables or the global window.a.

That knowledge allows code analysis tools — which might include JavaScript engines and particularly clever minifiers — to apply more optimisations. For example the second victim function could have the a variable completely optimised away to return 1. One use of eval and a lot of potential optimisations aren't going to be doable.

Of course in practice for a tiny function like a JSON eval​er, there isn't going to be a noticeable difference, but in general the thinking is:

  • avoid both approaches wherever possible (they are both disallowed in ECMAScript Fifth Edition's Strict Mode);
  • if you have to use one, new Function is preferable to eval, unless you really need the code to access the calling function's local variables.

As to why jQuery specifically uses new Function(), John Resig answered this on the jQuery forums

Using eval causes all sorts of problems for code minifiers since it's not clear what could be executing in the eval. Looking at the last results from that run it looks like new Function is fairly equivalent to eval and even slightly faster sometimes. The one exception was Safari 4 - but those results are dated, Safari 4 shipped with a native JSON.parse implementation, which we use.

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

The eval function is very fast. However, it can compile and execute any JavaScript program, so there can be security issues. The use of eval is indicated when the source is trusted and competent. It is much safer to use a JSON parser. In web applications over XMLHttpRequest, communication is permitted only to the same origin that provide that page, so it is trusted. But it might not be competent. If the server is not rigorous in its JSON encoding, or if it does not scrupulously validate all of its inputs, then it could deliver invalid JSON text that could be carrying dangerous script. The eval function would execute the script, unleashing its malice.

What exactly do you mean with safe? At least malicious code is not executed ;)

See also: Alternatives to JavaScript eval() for parsing JSON

Another point might be, that new Function() is considered to be a little faster than eval.

Update:

You can basically read about the same arguments in the comments on jQuery's .parseJSON() function.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论