Допустимо ли определять функции в результатах JSON?

Часть веб-сайта ответ JSON имел это (... добавил для контекста):

{..., now:function(){return(new Date).getTime()}, ...}

Является ли добавление анонимных функций в JSON? Я ожидал бы каждый раз, когда вы получите доступ к "времени", чтобы вернуть другое значение.

Ответ 1

Нет.

JSON предназначен исключительно для описания данных. Как отмечено в http://www.json.org, это "облегченный формат обмена данными". - не язык программирования.

Per http://en.wikipedia.org/wiki/JSON, поддерживаемые "базовые типы":

  • Число (целое, реальное или плавающее точка)
  • Строка (с двойным кавычкой Unicode с экранированием обратной косой черты)
  • Boolean (true и false)
  • Массив (упорядоченный последовательность значений, разделенных запятыми и заключены в квадратные скобки)
  • Объект (набор ключей: значение пары, разделенные запятыми и закрытые в фигурных скобках)
  • null

Ответ 2

Проблема заключается в том, что JSON как язык определения данных эволюционировал из JSON как обозначение объекта JavaScript. Поскольку Javascript поддерживает eval на JSON, законно ставить код JSON внутри JSON (в этом случае использования). Если вы используете JSON для передачи данных удаленно, то я бы сказал, что неправильная практика заключается в том, чтобы вводить методы в JSON, потому что вы, возможно, не хорошо моделировали взаимодействие с клиент-сервером. И, кроме того, когда вы хотите использовать JSON в качестве языка описания данных, я бы сказал, что вы можете попасть в проблему путем внедрения методов, потому что некоторые парсеры JSON были написаны с учетом только описания данных и могут не поддерживать определения методов в структуре.

Запись в Wikipedia JSON является хорошим аргументом в пользу того, что в JSON не используются методы, ссылаясь на проблемы безопасности:

Если вы абсолютно не доверяете источнику текста, и вам нужно разобрать и принять текст, который не является строго совместимым с JSON, вам следует избегать eval() и вместо этого использовать JSON.parse() или другой JSON-специфический синтаксический анализатор. Парсер JSON распознает только текст JSON и отклонит другой текст, который может содержать злонамеренный JavaScript. В браузерах, поддерживающих поддержку JSON, парсеры JSON также намного быстрее, чем eval. Ожидается, что поддержка родного JSON будет включена в следующий стандарт ECMAScript.

Ответ 3

Это не стандарт, насколько я знаю. Быстрый просмотр http://json.org/ подтверждает это.

Ответ 4

Обозначим один из spec - http://tools.ietf.org/html/rfc7159#section-12

Спецификация формата обмена данными JavaScript (JSON):

JSON - это подмножество JavaScript, но исключает назначение и вызов.

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

Итак, все ответы, которые утверждают, что функции не являются частью стандарта JSON, верны.

Официальный ответ: Нет, неверно определять функции в результатах JSON!


Ответ может быть да, потому что "код - это данные" и "данные - это код". Даже если JSON используется как независимый от языка формат сериализации данных, будет работать туннелирование "кода" через другие типы.

Строка JSON может использоваться для передачи функции JS в клиентский браузер для выполнения.

[{"data":[["1","2"],["3","4"]],"aFunction":"function(){return \"foo bar\";}"}]

Это приводит к вопросу вроде: "Выполнять JavaScript-код, сохраненный в виде строки".

Будьте готовы, чтобы поднять свой флаг eval() is evil "и поместить рядом с ним флаг" не туннелировать через JSON ".

Ответ 5

Нет, определенно нет.

Если вы используете достойный JSON-сериализатор, он не позволит вам сериализовать такую ​​функцию. Это действительный OBJECT, но недействительный JSON. Независимо от того, что этот сайт намерен, он не отправляет действительный JSON.

Ответ 6

JSON явно исключает функции, поскольку он не предназначен для данных только для JavaScript (несмотря на JS в названии).

Ответ 7

Короткий ответ НЕТ...

JSON - это текстовый формат, полностью независимый от языка, но использующий соглашения, знакомые программистам языков семейства C, включая C, C++, С#, Java, JavaScript, Perl, Python и многие другие. Эти свойства делают JSON идеальным языком обмена данными.

Посмотрите на причину, почему:

При обмене данными между браузером и сервером данные могут быть только текстовыми.

JSON - это текст, и мы можем преобразовать любой объект JavaScript в JSON и отправить JSON на сервер.

Мы также можем преобразовать любой JSON, полученный от сервера, в объекты JavaScript.

Таким образом, мы можем работать с данными как с объектами JavaScript, без сложного анализа и перевода.

Но подождите...

Есть еще способы сохранить вашу функцию, это широко не рекомендуется, но все же возможно:

Мы сказали, что вы можете сохранить string... как насчет преобразования вашей функции в строку тогда?

const data = {func: '()=>"a FUNC"'};

Затем вы можете зашифровать данные с помощью JSON.stringify(data) а затем с помощью JSON.parse для его анализа (если требуется этот шаг)...

И eval для выполнения строковой функции (перед этим просто сообщите, что использование eval широко не рекомендуется):

eval(data.func)(); //return "a FUNC"

Ответ 8

Не "Действителен? Нет, не в соответствии со спецификациями. Это можно сделать? Да, как показали другие. Рекомендуется ли это? Нет, из-за рисков безопасности. Люди все равно это делают? Да. Многие примеры, которые я видел в "диких", использовались со злым умыслом. (Вот как я в конечном итоге попал на эту публикацию.)

Ответ 9

Используя NodeJS (синтаксис commonJS), я смог заставить функционировать этот тип функций, у меня изначально была просто структура JSON внутри какого-то внешнего файла JS, но я хотел, чтобы эта структура была скорее классом, с методами, которые можно было бы определить при время выполнения.

Объявление 'Executor' в myJSON не требуется.

var myJSON = {
    "Hello": "World",
    "Executor": ""
}

module.exports = {
    init: () => { return { ...myJSON, "Executor": (first, last) => { return first + last } } }
}

Ответ 10

хотя eval не рекомендуется, это работает:

<!DOCTYPE html>
<html>
<body>

<h2>Convert a string written in JSON format, into a JavaScript function.</h2>

<p id="demo"></p>

<script>
    function test(val){return val + " it OK;}
    var someVar = "yup";
    var myObj = { "func": "test(someVar);" };
    document.getElementById("demo").innerHTML = eval(myObj.func);
</script>

</body>
</html>

Ответ 11

Функциональные выражения в JSON вполне возможны, просто не забудьте обернуть их в двойные кавычки. Вот пример, взятый из дизайна базы данных noSQL:

{
  "_id": "_design/testdb",
  "views": {
    "byName": {
      "map": "function(doc){if(doc.name){emit(doc.name,doc.code)}}"
    }
  }
}

Ответ 12

Оставьте кавычки выключенными...

var a = {"b":function(){alert('hello world');} };

a.b();