Почему использование JavaScript-функции eval - плохая идея? - PullRequest
502 голосов
/ 17 сентября 2008

Функция eval - это мощный и простой способ динамического генерирования кода, так что же такое предостережения?

Ответы [ 25 ]

368 голосов
/ 17 сентября 2008
  1. Неправильное использование eval открывает ваш код для инъекционных атак

  2. Отладка может быть более сложной (без номеров строк и т. д.)

  3. eval'd-код выполняется медленнее (нет возможности компилировать / кэшировать eval'd-код)

Редактировать: Как @Jeff Walden указывает в комментариях, # 3 сегодня менее верен, чем это было в 2008 году. Однако, хотя может происходить некоторое кэширование скомпилированных скриптов, это будет ограничено только скриптами, которые eval повторял без изменений. Более вероятным сценарием является то, что вы оцениваете скрипты, которые каждый раз подвергались небольшим изменениям и поэтому не могли быть кэшированы. Давайте просто скажем, что НЕКОТОРЫЙ eval'd код выполняется медленнее.

343 голосов
/ 18 сентября 2008

Eval не всегда зло. Есть моменты, когда это совершенно уместно.

Однако eval в настоящее время и исторически массово используется людьми, которые не знают, что они делают. К сожалению, это включает людей, пишущих учебники по JavaScript, а в некоторых случаях это может иметь последствия для безопасности - или, чаще, простые ошибки. Таким образом, чем больше мы можем сделать, чтобы поставить вопросительный знак над eval, тем лучше. Каждый раз, когда вы используете eval, вам нужно проверять, что вы делаете, потому что есть вероятность, что вы можете сделать это лучше, безопаснее и чище.

Чтобы дать слишком типичный пример, установить цвет элемента с идентификатором, хранящимся в переменной 'potato':

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

Если бы авторы приведенного выше кода имели представление об основах работы объектов JavaScript, они бы поняли, что вместо литеральных точечных имен можно использовать квадратные скобки, устраняя необходимость в eval: *

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

... который намного легче читать, а также менее потенциально глючит.

(Но тогда кто-то, кто / действительно / знал, что они делают, скажет:

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

, что более надежно, чем хитрый старый прием доступа к элементам DOM прямо из объекта документа.)

36 голосов
/ 17 сентября 2008

Я считаю, что это потому, что он может выполнять любую функцию JavaScript из строки. С его помощью людям проще внедрить в приложение мошеннический код.

26 голосов
/ 17 сентября 2008

На ум приходят два момента:

  1. Безопасность (но пока вы сами генерируете строку для оценки, это может быть проблемой)

  2. Производительность: до тех пор, пока исполняемый код неизвестен, его нельзя оптимизировать. (о javascript и производительности, конечно же презентация Стива Йегге )

20 голосов
/ 17 сентября 2008

Передача пользовательского ввода в eval () представляет угрозу безопасности, но каждый вызов eval () создает новый экземпляр интерпретатора JavaScript. Это может быть ресурсный боров.

17 голосов
/ 17 сентября 2008

Обычно это проблема, только если вы передаете пользовательский ввод.

15 голосов
/ 17 сентября 2008

В основном, это намного сложнее поддерживать и отлаживать. Это как goto. Вы можете использовать его, но это усложняет поиск проблем и усложняет работу с людьми, которым может потребоваться внести изменения позже.

13 голосов
/ 18 сентября 2008

Следует иметь в виду, что вы часто можете использовать eval () для выполнения кода в иным образом ограниченной среде - сайты социальных сетей, которые блокируют определенные функции JavaScript, иногда можно обмануть, разбив их на блоки eval -

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

Так что, если вы хотите запустить какой-нибудь код JavaScript, который иначе не мог бы быть разрешен ( Myspace , я смотрю на вас ...), тогда eval () может быть полезным трюком.

Однако, по всем причинам, указанным выше, вы не должны использовать его для своего собственного кода, где у вас есть полный контроль - это просто не нужно, и лучше отойти на полку «хитрых хаков JavaScript».

11 голосов
/ 17 сентября 2008

Если вы не разрешите eval () динамический контент (с помощью cgi или input), он будет таким же безопасным и надежным, как и любой другой JavaScript на вашей странице.

7 голосов
/ 03 января 2012

Наряду с остальными ответами, я не думаю, что у утверждений eval может быть продвинутая минимизация.

...