Методи "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... }
Повертаючись до початкового питання, яке було поставлене в 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');
Це може бути корисно, але якщо у вас немає конкретних потреб, це, мабуть, не те, що ви хочете.