JQuery использует (новая функция («возврат» + данные)) (); вместо eval (данные); разобрать JSON, зачем? - PullRequest
17 голосов
/ 15 марта 2010

Эта ссылка показывает, что jQuery использует (new Function("return " + data))(); для более старых браузеров для анализа строки JSON вместо eval().

Каковы преимущества этого? Что если строка JSON не является безопасной ?

Ответы [ 3 ]

32 голосов
/ 15 марта 2010

Цитата в ответе Ника намекает на это. Это не большая разница, но ощущение, что eval «хуже», чем new Function. Не с точки зрения безопасности - они оба одинаково бесполезны перед лицом ненадежного ввода, но, надеюсь, ваше веб-приложение не возвращает ненадежные строки JSON - но с точки зрения странного уровня языка и, следовательно, сопротивления оптимизации.

В частности:

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

дает 2. Строка ed eval оперировала областью локальной переменной victim! Это то, что обычная пользовательская функция никогда не сможет сделать; eval может сделать это только потому, что это темная магия.

Использование обычной функции вместо этого убирает этот элемент магии:

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

в вышеприведенном, возвращенное a остается 1; новая функция может работать только со своими локальными переменными или глобальными window.a.

Это знание позволяет инструментам анализа кода - которые могут включать механизмы JavaScript и особенно умные минификаторы - применять больше оптимизаций. Например, вторая функция victim может иметь переменную a, полностью оптимизированную до return 1. Одно использование eval и много потенциальных оптимизаций не будут выполнимы.

Конечно, на практике для такой крошечной функции, как JSON eval er, заметной разницы не будет, но в целом мысль такова:

  • по возможности избегать обоих подходов (оба они запрещены в строгом режиме пятого издания ECMAScript);
  • если вам нужно его использовать, new Function предпочтительнее eval, если только вам действительно не нужен код для доступа к локальным переменным вызывающей функции.
11 голосов
/ 15 марта 2010

Относительно того, почему jQuery специально использует new Function(), Джон Ресиг ответил на форумах jQuery

Использование eval вызывает все виды проблем для минификаторов кода, так как неясно, что может выполняться в eval. Если посмотреть на последние результаты этого запуска, кажется, что новая функция довольно эквивалентна eval и даже иногда немного быстрее. Единственным исключением был Safari 4 - но эти результаты датированы, Safari 4 поставляется с собственной реализацией JSON.parse, которую мы используем.

3 голосов
/ 15 марта 2010

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

Функция eval очень быстрая. Однако он может скомпилировать и выполнить любую программу JavaScript , поэтому могут возникнуть проблемы с безопасностью. Использование eval указывается, когда источником является доверенный и компетентный . Гораздо безопаснее использовать анализатор JSON . В веб-приложениях через XMLHttpRequest общение разрешено только с тем же источником, который предоставляет эту страницу, поэтому он является доверенным. Но это может не быть компетентным . Если сервер не является строгим в своей кодировке JSON или не тщательно проверяет все свои входные данные, он может доставить недопустимый текст JSON, который может содержать опасный сценарий . Функция eval будет выполнять скрипт, раскрывая его злобу.

Что именно вы имеете в виду под safe ? По крайней мере, вредоносный код не выполняется;)

См. Также: Альтернативы JavaScript eval () для анализа JSON

Другим моментом может быть то, что new Function() считается немного быстрее , чем eval.

Обновление:

Вы можете прочитать об этих же аргументах в комментариях к функции .parseJSON() jQuery .

.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...