Безопасное превращение строки JSON в объект

Учитывая строку данных JSON, как я могу безопасно превратить эту строку в объект JavaScript?

Очевидно, что я могу сделать это небезопасно с чем-то вроде:

var obj = eval("(" + json + ')');

но это делает меня уязвимым для строки JSON, содержащей другой код, который кажется очень опасным для простой оценки.

5.09.2008 00:12:01
На большинстве языков eval несет дополнительный риск. Эвал оставляет открытую дверь для использования хакерами. ОДНАКО помните, что все JavaScript работает на клиенте. Ожидать, что это будет изменено хакерами. Они могут ПРОВЕРИТЬ все, что захотят, просто используя консоль. Вы должны построить свою защиту на стороне сервера.
Beachhouse 7.02.2013 17:34:48
Хорошо, сейчас 2014, и вы никогда не должны использовать его evalдля анализа строки JSON, потому что вы подвергаете свой код «внедрению кода». Используйте JSON.parse(yourString)вместо этого.
Daniel 22.10.2014 06:27:08
Являются ли данные JSON литералом?
shanechiu 25.09.2017 10:02:18
@shanechiu: если вы имеете в виду скалярный тип данных, то да. Это просто строка с синтаксисом ключ-значение.
0zkr PM 17.09.2018 18:09:38
27 ОТВЕТОВ
РЕШЕНИЕ

JSON.parse(jsonString) это чистый подход JavaScript, если вы можете гарантировать достаточно современный браузер.

1944
26.03.2018 18:41:03
Я почти уверен, что это безопасно для Node.js
Stephen 18.10.2011 17:07:01
@vsync вы понимаете, что это ЕДИНСТВЕННЫЙ чистый ответ Javascript ... если вы прочитаете описание тега javascript, вы увидите это ... " Если тег для фреймворка / библиотеки также не включен, чистый ответ JavaScript ожидается. ".. Я даю это +1 за то, что был единственным ответом javascript ...
iConnor 21.07.2013 22:31:21
Если вы работаете с NodeJS, я не смог бы загрузить jQuery просто для анализа jsonString в объект JSON. Итак, ответ Джонатана upvote
Antony 15.10.2013 16:49:03
По этой ссылке поддерживается IE8 +, хотя там написано:Requires document to be in IE8+ standards mode to work in IE8.
JoshuaDavid 12.01.2015 21:19:58

Я не уверен насчет других способов сделать это, но вот как вы это делаете в Prototype (учебник по JSON) .

new Ajax.Request('/some_url', {
  method:'get',
  requestHeaders: {Accept: 'application/json'},
  onSuccess: function(transport){
    var json = transport.responseText.evalJSON(true);
  }
});

Вызов evalJSON()с истиной в качестве аргумента дезинфицирует входящую строку.

23
27.11.2019 00:59:49

Этот ответ для IE <7, для современных браузеров проверьте ответ Джонатана выше.

Этот ответ устарел, и ответ Джонатана выше ( JSON.parse(jsonString)) теперь является лучшим ответом .

JSON.org имеет парсеры JSON для многих языков, включая четыре различных для JavaScript. Я считаю, что большинство людей считают json2.js своей реализацией.

159
27.11.2019 00:58:19
Я бы хотел, чтобы люди перестали голосовать за этот ответ. Он был точным, когда он был опубликован в 2008 году. Просто добавьте новый.
John 16.01.2015 02:26:13
Если ответ сейчас устарел, рассмотрите возможность его обновления.
Sotirios Delimanolis 7.03.2015 05:35:17
для IE <8 вы должны использовать это.
Mahmoodvcs 16.07.2015 20:22:00

Если вы используете jQuery , вы также можете использовать:

$.getJSON(url, function(data) { });

Тогда вы можете делать такие вещи, как

data.key1.something
data.key1.something_else

и т.п.

17
27.11.2019 01:02:57
Вы используете JQuery, не так ли?
Alexandre C. 2.09.2010 14:09:29
$.ajax({
  url: url,
  dataType: 'json',
  data: data,
  success: callback
});

Обратному вызову передаются возвращенные данные, которые будут объектом или массивом JavaScript, как определено структурой JSON, и проанализированы с использованием $.parseJSON()метода.

15
16.07.2015 23:38:26

Метод jQuery устарел. Используйте этот метод вместо:

let jsonObject = JSON.parse(jsonString);

Исходный ответ с использованием устаревшей функциональности jQuery :

Если вы используете jQuery, просто используйте:

jQuery.parseJSON( jsonString );

Это именно то, что вы ищете (см. Документацию jQuery ).

877
24.04.2017 15:50:32
Есть ли причина использовать это поверх JSON.parse ()?
Jon 20.03.2016 02:02:11
jQuery.parseJSONпо умолчанию используется, JSON.parseесли он существует, поэтому единственная причина использовать его по сравнению с реальным - это если вам нужен запасной вариант для <IE7. В jQuery 1.6 это было изменено: james.padolsey.com/jquery/#v=1.6.0&fn=jQuery.parseJSON
Karl-Johan Sjögren 5.04.2016 20:49:56
Обновление 2016: Начиная с jQuery 3.0, $ .parseJSON устарел, и вместо него следует использовать собственный метод JSON.parse.
jkdev 28.06.2016 22:36:44

Это, кажется, проблема:

Ввод, полученный через веб-сокет Ajax и т. Д., И он будет в формате String, но вам необходимо знать, так ли это JSON.parsable. Двойным является то, что, если вы всегда запускаете его JSON.parse, программа МОЖЕТ продолжить «успешно», но вы все равно увидите ошибку, выданную в консоли с ужасом "Error: unexpected token 'x'".

var data;

try {
  data = JSON.parse(jqxhr.responseText);
} catch (_error) {}

data || (data = {
  message: 'Server error, please retry'
});
22
27.11.2019 01:02:00
NO. Проблема заключается в том, что вы ожидаете JSON-объект и в итоге можете получить что- (function(){ postCookiesToHostileServer(); }());то еще более неприятное в контексте Node.
Yaur 15.04.2014 21:56:38
Хорошо JSON.parse очищает ввод функций (что в этом случае не помогло бы как его IIF -> объект). Кажется, лучший способ решить эту тему - попробовать / поймать. (См. Правку)
Cody 24.04.2014 21:11:43

Используйте простой пример кода в " JSON.parse () ":

var jsontext = '{"firstname":"Jesper","surname":"Aaberg","phone":["555-0100","555-0120"]}';
var contact = JSON.parse(jsontext);

и наоборот:

var str = JSON.stringify(arr);
73
27.11.2019 00:59:25

Попробуйте использовать метод с этим объектом данных. например: Data='{result:true,count:1}'

try {
  eval('var obj=' + Data);
  console.log(obj.count);
}
catch(e) {
  console.log(e.message);
}

Этот метод действительно помогает в Nodejs, когда вы работаете с программированием последовательного порта

9
17.03.2020 12:44:43
Это действительно забавно, как люди зациклены на «eval is evil», и они сделают все, чтобы избежать этого, даже переписав всю функциональность eval ..
diynevala 12.09.2014 10:52:22
Является ли консенсус этот трюк безопасным методом превращения строки в объект JSON? Я мог бы использовать это, поскольку не требуется дополнительный импорт JS.
Whome 13.10.2014 10:48:16
ЛЮБОЙ подход, использующий evalили Functionодинаково уязвимый
Slai 3.06.2018 12:32:30
undefined; function bye() {...} bye();
Salvioner 22.01.2019 12:41:47

Просто для удовольствия, вот способ использования функции:

 jsonObject = (new Function('return ' + jsonFormatData))()
12
27.11.2019 01:03:26
Интересный подход, я не уверен, что использовал бы это с доступным JSON.Parse, но приятно видеть, что кто-то думает вне коробки.
user1017882 3.09.2015 10:58:00
Это очень похоже на простое использование evalи не безопасно. : P
Florrie 7.11.2015 12:18:50
Это имеет все недостатки использования, evalно его сложнее и труднее понять сопровождающим.
Quentin 24.11.2015 15:06:53

Я нашел «лучший» способ:

В CoffeeScript:

try data = JSON.parse(jqxhr.responseText)
data ||= { message: 'Server error, please retry' }

В Javascript:

var data;

try {
  data = JSON.parse(jqxhr.responseText);
} catch (_error) {}

data || (data = {
  message: 'Server error, please retry'
});
5
18.02.2015 13:38:07

Использование JSON.parse, вероятно, лучший способ.

Вот пример живой демо .

var jsonRes = '{ "students" : [' +
          '{ "firstName":"Michel" , "lastName":"John" ,"age":18},' +
          '{ "firstName":"Richard" , "lastName":"Joe","age":20 },' +
          '{ "firstName":"James" , "lastName":"Henry","age":15 } ]}';
var studentObject = JSON.parse(jsonRes);
9
27.11.2019 01:04:23

Самый простой способ с использованием parse()метода:

var response = '{"result":true,"count":1}';
var JsonObject= JSON.parse(response);

Затем вы можете получить значения элементов JSON, например:

var myResponseResult = JsonObject.result;
var myResponseCount = JsonObject.count;

Используя jQuery, как описано в jQuery.parseJSON()документации:

JSON.parse(jsonString);
9
27.11.2019 01:05:43

JSON.parse() преобразует любую строку JSON, переданную в функцию, в объект JSON.

Чтобы лучше это понять, нажмите, F12чтобы открыть «Проверка элемента» в браузере и перейти к консоли, чтобы написать следующие команды:

var response = '{"result":true,"count":1}'; //sample json object(string form)
JSON.parse(response); //converts passed string to JSON Object.

Теперь запустите команду:

console.log(JSON.parse(response));

Вы получите вывод как объект {result: true, count: 1}.

Чтобы использовать этот объект, вы можете присвоить его переменной, возможно obj:

var obj = JSON.parse(response);

Используя оператор obj«точка» ( .), вы можете получить доступ к свойствам объекта JSON.

Попробуйте запустить команду:

console.log(obj.result);
3
27.11.2019 01:11:59
JSON.parse(jsonString);

json.parse превратится в объект.

3
19.12.2016 13:05:06

Разбор JSON - это всегда боль. Если ввод не такой, как ожидалось, он выдает ошибку и вылетает, что вы делаете.

Вы можете использовать следующую крошечную функцию для безопасного анализа вашего ввода. Он всегда поворачивает объект, даже если ввод недействителен или уже является объектом, что лучше для большинства случаев:

JSON.safeParse = function (input, def) {
  // Convert null to empty object
  if (!input) {
    return def || {};
  } else if (Object.prototype.toString.call(input) === '[object Object]') {
    return input;
  }
  try {
    return JSON.parse(input);
  } catch (e) {
    return def || {};
  }
};
4
27.11.2019 01:07:35
Object.prototype.toString.call(input) === '[object Object]'должно быть typeof input === 'object'ИМО
Serge K. 6.12.2017 16:16:22
typeof input возвращает объект для нуля и массивов. Так что это не безопасный способ сделать это.
Tahsin Turkoz 9.01.2018 20:13:02
Вы уже рассмотрели этот nullслучай раньше, и массив является объектом. Если вы хотите проверить это, вы можете использовать instanceof. Более того, если вы передадите этой функции значение an Array, она будет ловить и return defтогда, когда она могла бы вернуть совершенно точный массив.
Serge K. 10.01.2018 08:56:29
Мой комментарий был о здравом смысле при ловле предметов. Моя функция может иметь несколько предупреждений, но использование ввода typeof не является предпочтительным способом обнаружения объектов в целом.
Tahsin Turkoz 10.01.2018 09:30:05
IMO, здравый смысл не использует toString()метод для проверки, является ли переменная объектом или нет. Смотрите AngularJS , jQuery , Underscore или даже разработчиков
Serge K. 10.01.2018 13:34:18

Преобразование объекта в JSON, а затем его разбор работает для меня, например:

JSON.parse(JSON.stringify(object))
2
28.12.2017 18:16:34
Вы пропустили закрывающую скобку.
Salomon Zhang 20.12.2017 01:13:40

Вы также можете использовать reviverфункцию для фильтрации.

var data = JSON.parse(jsonString, function reviver(key, value) {
   //your code here to filter
});

Для получения дополнительной информации читайте JSON.parse.

0
27.11.2019 01:15:42

Официальная документация :

JSON.parse()Метод анализирует строку JSON, конструируя значение JavaScript или объект , описанный в строке. reviverМожет быть предоставлена необязательная функция для выполнения преобразования результирующего объекта перед его возвращением.

Синтаксис:

JSON.parse(text[, reviver])

Параметры:

text : Строка для анализа в формате JSON. См. Объект JSON для описания синтаксиса JSON.

reviver (optional) : Если функция, это предписывает, как значение, первоначально произведенное синтаксическим анализом, преобразовано, прежде чем будет возвращено.

Возвращаемое значение

Объект, соответствующий заданному тексту JSON.

Исключения

Выдает исключение SyntaxError, если строка для анализа недопустима в формате JSON.

3
27.11.2019 01:15:09

Более старый вопрос, я знаю, однако никто не заметил это решение, используя new Function()анонимную функцию, которая возвращает данные.


Просто пример:

 var oData = 'test1:"This is my object",test2:"This is my object"';

 if( typeof oData !== 'object' )
  try {
   oData = (new Function('return {'+oData+'};'))();
  }
  catch(e) { oData=false; }

 if( typeof oData !== 'object' )
  { alert( 'Error in code' ); }
 else {
        alert( oData.test1 );
        alert( oData.test2 );
      }

Это немного более безопасно, потому что он выполняется внутри функции и не компилируется в вашем коде напрямую. Поэтому, если внутри него есть объявление функции, оно не будет привязано к объекту окна по умолчанию.

Я использую это для простой и быстрой «компиляции» настроек конфигурации элементов DOM (например, атрибута данных).

0
19.02.2018 01:32:24

Попробуйте это. Это написано в машинописи.

         export function safeJsonParse(str: string) {
               try {
                 return JSON.parse(str);
                   } catch (e) {
                 return str;
                 }
           }
-1
30.05.2018 06:31:48
Я новичок в Typescript. Какую пользу это добавляет JSON.parse()?
Marc L. 19.10.2018 12:30:14
Если возникнет какое-либо исключение, будет возвращена сама входная строка
Supun Dharmarathne 31.10.2018 06:55:07

Разобрать строку JSON JSON.parse(), и данные станут объектом JavaScript:

JSON.parse(jsonString)

Здесь JSON представляет для обработки набора данных JSON.

Представьте, что мы получили этот текст с веб-сервера:

'{ "name":"John", "age":30, "city":"New York"}'

Для анализа в объект JSON:

var obj = JSON.parse('{ "name":"John", "age":30, "city":"New York"}'); 

Вот objсоответствующий объект JSON, который выглядит следующим образом:

{ "name":"John", "age":30, "city":"New York"}

Чтобы получить значение, используйте .оператор:

obj.name // John
obj.age //30

Преобразуйте объект JavaScript в строку с помощью JSON.stringify().

2
27.11.2019 01:17:58

Резюме:

Javascript (как браузер, так и NodeJS) имеют встроенный JSONобъект. На этом объекте есть 2 удобных способа борьбы с JSON. Они следующие:

  1. JSON.parse() Принимает в JSONкачестве аргумента, возвращает объект JS
  2. JSON.stringify() Принимает объект JS в качестве аргумента, возвращает JSONобъект

Другие приложения:

К тому же для очень удобного обращения с JSONними можно использовать другие средства. Сочетание обоих JSONметодов позволяет очень легко сделать глубокие клоны массивов или объектов. Например:

let arr1 = [1, 2, [3 ,4]];
let newArr = arr1.slice();

arr1[2][0] = 'changed'; 
console.log(newArr); // not a deep clone

let arr2 = [1, 2, [3 ,4]];
let newArrDeepclone = JSON.parse(JSON.stringify(arr2));

arr2[2][0] = 'changed'; 
console.log(newArrDeepclone); // A deep clone, values unchanged

0
18.08.2018 10:00:42

Если у нас есть такая строка:

"{\"status\":1,\"token\":\"65b4352b2dfc4957a09add0ce5714059\"}"

тогда мы можем просто использовать JSON.parseдважды, чтобы преобразовать эту строку в объект JSON:

var sampleString = "{\"status\":1,\"token\":\"65b4352b2dfc4957a09add0ce5714059\"}"
var jsonString= JSON.parse(sampleString)
var jsonObject= JSON.parse(jsonString)

И мы можем извлечь значения из объекта JSON, используя:

// instead of last JSON.parse:
var { status, token } = JSON.parse(jsonString);

Результат будет:

status = 1 and token = 65b4352b2dfc4957a09add0ce5714059
3
27.11.2019 01:08:42
/**
 * Safely turning a JSON string into an object
 *
 * @param {String} str - JSON String
 * @returns deserialized object, false if error
 */
export function jsonParse(str) {
  let data = null;
  try {
    data = JSON.parse(str);
  } catch (err) {
    return false;
  }
  return data;
}
-1
30.12.2019 05:28:56

JSON.parse - это правильный способ преобразования строки в объект, но если анализируемая строка не является объектом или строка неверна, она выдаст ошибку, которая приведет к разрыву остальной части кода, поэтому идеально подходит для переноса функции JSON.parse внутри try-catch

try{
   let obj = JSON.parse(string);
}catch(err){
   console.log(err);
}
0
15.01.2020 07:43:11

Просто на разбор обложки для разных типов ввода

Разобрать данные с помощью JSON.parse (), и данные станут объектом JavaScript.

var obj = JSON.parse('{ "name":"John", "age":30, "city":"New York"}');

При использовании JSON.parse () в JSON, производном от массива, метод возвращает массив JavaScript вместо объекта JavaScript.

var myArr = JSON.parse(this.responseText);
console.log(myArr[0]);

Объекты даты не допускаются в JSON. Для Даты сделать что-то вроде этого

var text = '{ "name":"John", "birth":"1986-12-14", "city":"New York"}';
var obj = JSON.parse(text);
obj.birth = new Date(obj.birth);

Функции не допускаются в JSON. Если вам нужно включить функцию, напишите ее в виде строки.

var text = '{ "name":"John", "age":"function () {return 30;}", "city":"New York"}';
var obj = JSON.parse(text);
obj.age = eval("(" + obj.age + ")");
1
23.02.2020 05:34:13