Методы "eval ()" и "JSON.parse ()" используют взаимоисключающие форматы.
- С круглыми скобками "eval ()" требуется .
- С круглыми скобками "JSON.parse ()" запрещено .
Осторожно, есть функции "stringify ()", которые создают формат "eval". Для ajax вы должны использовать только формат JSON.
В то время как «eval» включает в себя весь язык JavaScript, JSON использует лишь небольшую часть языка. Среди конструкций на языке JavaScript, которые должен распознавать eval, есть «Оператор блока» (a.k.a. «Составной оператор») ; которая представляет собой пару или фигурные скобки "{}" с некоторыми инструкциями внутри. Но фигурные скобки также используются в синтаксисе объектных литералов. Интерпретация дифференцируется контекстом, в котором появляется код. Что-то может выглядеть как объект, буквальный для вас, но «eval» увидит это как составное утверждение.
На языке JavaScript литералы объектов встречаются справа от присваивания.
var myObj = { ...some..code..here... };
Литералы объектов не встречаются сами по себе.
{ ...some..code..here... } // this looks like a compound statement
Возвращаясь к первоначальному вопросу OP, заданному в 2008 году, он спросил, почему в eval () не удается выполнить следующее:
{ title: "One", key: "1" }
Ответ в том, что это выглядит как сложное утверждение. Чтобы преобразовать его в объект, вы должны поместить его в контекст, где составное утверждение невозможно. Это можно сделать, поставив вокруг него скобки
( { title: "One", key: "1" } ) // not a compound statment, so must be object literal
ОП также спросил, почему подобное утверждение успешно успешно подтвердилось:
[ { 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'); // generates eval() format
Это может быть полезно, но если у вас нет особых потребностей, это, вероятно, не то, что вы хотите.