Методы eval () и JSON.parse () используют взаимоисключающие форматы.
- Круглые скобки "eval ()" обязательны .
- Скобки с «JSON.parse ()» запрещены .
Остерегайтесь, есть функции "stringify ()", которые производят формат "eval". Для ajax следует использовать только формат JSON.
В то время как eval включает в себя весь язык JavaScript, JSON использует только крошечное подмножество языка. Среди конструкций языка JavaScript, которые должен распознавать eval, есть «Блок-оператор» (он же «составной оператор»). ; который представляет собой пару или фигурные скобки "{}" с некоторыми операторами внутри. Но фигурные скобки также используются в синтаксисе объектных литералов. Интерпретация зависит от контекста, в котором появляется код. Что-то может показаться вам литералом объекта, но eval будет рассматривать это как составной оператор.
В языке JavaScript объектные литералы встречаются справа от назначения.
var myObj = { ...some..code..here... };
Литералы объекта не встречаются сами по себе.
{ ...some..code..here... }
Возвращаясь к исходному вопросу OP, заданному в 2008 году, он спросил, почему следующее не работает в eval ():
{ title: "One", key: "1" }
Ответ в том, что это похоже на составное утверждение. Чтобы преобразовать его в объект, вы должны поместить его в контекст, в котором составной оператор невозможен. Это делается путем заключения вокруг него скобок
( { title: "One", key: "1" } )
OP также спросил , почему подобное заявление сделало успешно Eval:
[ { title: "One", key: "1" }, { title: "Two", key: "2" } ]
Применяется тот же ответ - фигурные скобки находятся в контексте, где составной оператор невозможен. Это контекст массива " [...]
", и массивы могут содержать объекты, но не могут содержать операторов.
В отличие от eval (), JSON очень ограничен в своих возможностях. Ограничение сделано намеренно. Разработчик JSON задумал минималистское подмножество JavaScript, используя только синтаксис, который может отображаться справа от задания. Итак, если у вас есть код, который правильно разбирает в JSON ...
var myVar = JSON.parse("...some...code...here...");
... это означает, что он также будет выполнять юридический синтаксический анализ в правой части задания, например ...
var myVar = ...some..code..here... ;
Но это не единственное ограничение JSON. В языка BNF для JSON очень проста. Например, он не позволяет использовать одинарные кавычки для обозначения строк (как в JavaScript и Perl), и у него нет способа выразить одиночный символ в виде байта (как это делает 'C'). К сожалению, он также не допускает комментариев (что было бы очень хорошо при создании файлов конфигурации). Положительным моментом всех этих ограничений является то, что синтаксический анализ JSON выполняется быстро и не дает возможности для внедрения кода (угроза безопасности).
Из-за этих ограничений в JSON не используются скобки. Следовательно, скобка в строке JSON является недопустимым символом.
Всегда используйте формат JSON с ajax по следующим причинам:
- Типичный конвейер ajax будет настроен для JSON.
- Использование eval () будет подвергнуто критике как угроза безопасности.
В качестве примера конвейера ajax рассмотрим программу, которая включает в себя сервер Node и клиент jQuery. Клиентская программа использует вызов jQuery, имеющий форму $.ajax({dataType:'json',...etc.});
. JQuery создает объект jqXHR для последующего использования, затем упаковывает и отправляет связанный запрос. Сервер принимает запрос, обрабатывает его и готов ответить. Серверная программа вызовет метод res.json(data)
для упаковки и отправит ответ. На стороне клиента jQuery принимает ответ, обращается к связанному объекту jqXHR и обрабатывает данные в формате JSON. Все это работает без необходимости ручного преобразования данных. В ответе нет явного вызова JSON.stringify () на сервере Node и нет явного вызова JSON.parse () на клиенте; это все сделано за вас.
Использование eval связано с рисками безопасности внедрения кода. Вы можете подумать, что этого не может быть, но хакеры могут проявить изобретательность. Кроме того, eval проблематичен для оптимизации Javascript.
Если вы обнаружите, что используете функцию «stringify ()», имейте в виду, что некоторые функции с таким именем будут создавать строки, совместимые с «eval», а не с JSON. Например, в Node следующее дает вам функцию, которая создает строки в формате, совместимом с eval:
var stringify = require('node-stringify');
Это может быть полезно, но, если у вас нет особой потребности, вероятно, это не то, что вам нужно.