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

1215

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

Очевидно, что вы можете сделать это небезопасно с чем-то вроде...

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

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

  • 73
    В большинстве языков eval несет дополнительный риск. Эвал оставляет открытую дверь для использования хакерами. ОДНАКО помните, что все JavaScript работает на клиенте. Ожидать, что это будет изменено хакерами. Они могут ПРОВЕРИТЬ все, что захотят, просто используя консоль. Вы должны построить свою защиту на стороне сервера.
  • 17
    Хорошо, сейчас 2014, и вы никогда не должны использовать eval для анализа строки JSON, потому что вы подвергаете свой код «внедрению кода». JSON.parse(yourString) используйте JSON.parse(yourString) .
Показать ещё 2 комментария
Теги:

26 ответов

1668
Лучший ответ

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

  • 68
    Я уверен, что это безопасно для Node.js
  • 1
    Он поддерживается не во всех браузерах, но скрипт по ссылке ниже добавляет его в браузеры, в которых его нет: github.com/douglascrockford/JSON-js/blob/master/json2.js
Показать ещё 9 комментариев
905

Метод jQuery теперь устарел. Вместо этого используйте этот метод:

let jsonObject = JSON.parse(jsonString);

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

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

jQuery.parseJSON( jsonString );

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

  • 6
    Есть ли причина использовать это поверх JSON.parse ()?
  • 7
    jQuery.parseJSON умолчанию использует JSON.parse если он существует, поэтому единственная причина использовать его JSON.parse реальной - это если вам нужен запасной вариант для <IE7. В jQuery 1.6 это было изменено: james.padolsey.com/jquery/#v=1.6.0&fn=jQuery.parseJSON
Показать ещё 1 комментарий
136

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

Изменение: этот ответ устарел, и Джонатан ответил выше (JSON.parse(jsonString)) теперь лучший ответ.

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

  • 21
    Я бы хотел, чтобы люди перестали голосовать за этот ответ. Он был точным, когда он был опубликован в 2008 году. Просто добавьте новый.
  • 17
    Если ответ устарел, рассмотрите возможность его обновления.
Показать ещё 1 комментарий
60

Используйте простой код, представленный в следующей ссылке в MSDN.

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

и наоборот

var str = JSON.stringify(arr);
19

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

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

Вызов evalJSON() с true, поскольку аргумент дезинфицирует входящую строку.

16

Кажется, это проблема:

Вход получен, через ajax websocket и т.д., и он всегда будет в формате String, но вам нужно знать, является ли это JSON.parsable. Touble - это то, что если вы всегда запускаете его через JSON.parse, программа МОЖЕТ продолжить "успешно", но вы все равно увидите ошибку, выброшенную в консоли с ужасным "Ошибка: неожиданный токен" x ".

var data;

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

data || (data = {
  message: 'Server error, please retry'
});
  • 0
    NO. Проблема заключается в том, что вы ожидаете объект JSON и можете получить (function(){ postCookiesToHostileServer(); }()); или даже более неприятные вещи в контексте Node.
  • 0
    Хорошо JSON.parse очищает ввод функций (что в этом случае не помогло бы как его IIF -> объект). Кажется, лучший способ решить эту тему - попробовать / поймать. (См. Редактировать)
12

Если вы используете jQuery, вы также можете просто сделать $.getJSON(url, function(data) { });

Затем вы можете делать такие вещи, как data.key1.something, data.key1.something_else и т.д.

  • 0
    Вы используете JQuery, не так ли?
11
$.ajax({
  url: url,
  dataType: 'json',
  data: data,
  success: callback
});

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

10

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

 jsonObject = (new Function('return ' + jsonFormatData))()
  • 0
    Интересный подход, я не уверен, что использовал бы это с доступным JSON.Parse, но приятно видеть, что кто-то думает вне коробки.
  • 3
    Это очень похоже на использование eval и не безопасно. :П
Показать ещё 1 комментарий
9

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

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

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

  • 0
    Это действительно забавно, как люди зациклены на «eval is evil», и они сделают все, чтобы избежать этого, даже переписав всю функциональность eval…
  • 0
    Является ли консенсус этот трюк безопасным методом превращения строки в объект JSON? Я мог бы использовать это, так как не требуется дополнительный импорт JS.
Показать ещё 2 комментария
7

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

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

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

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

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

JSON.parse(jsonString);
6

Использование 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);
6

Я успешно использовал json_sans_eval некоторое время. По словам его автора, он более безопасен, чем json2.js.

4

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

В 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'
});
2

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

JSON.parse(JSON.stringify(object))
  • 1
    Вы пропустили закрывающую скобку.
2

Разбор 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 || {};
  }
};
  • 0
    Object.prototype.toString.call(input) === '[object Object]' должен быть typeof input === 'object' IMO
  • 0
    Ввод typeof возвращает объект для нуля и массивов. Так что это не безопасный способ сделать это.
Показать ещё 5 комментариев
2
JSON.parse(jsonString);

json.parse изменится на объект.

1

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

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

Синтаксис

JSON.parse(text[, reviver])

параметры

текст

Строка для синтаксического анализа как JSON. См. Объект JSON для описания синтаксиса JSON.

reviver (необязательно)

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

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

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

Исключения

Выдает исключение SyntaxError, если строка для разбора недействительна JSON.

1

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

Для лучшего понимания нажмите F12, чтобы открыть Inspect Element своего браузера и перейти к консоли, чтобы написать следующие команды: -

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));

вы получите результат как Object {result: true, count: 1}.

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

var obj = JSON.parse(response);

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

Попробуйте выполнить команду

console.log(obj.result);
0

Резюме:

Javascript (как браузер, так и NodeJS) имеет встроенный объект JSON. На этом объекте есть два удобных метода работы с 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

Разделите строку 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().

0

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

         export function safeJsonParse(str: string) {
               try {
                 return JSON.parse(str);
                   } catch (e) {
                 return str;
                 }
           }
  • 0
    Я новичок в Typescript. Какую пользу это добавляет к JSON.parse() ?
  • 0
    Если произошло какое-либо исключение, это вернет саму входную строку
0

Если ваш JavaScript находится в Mootools, JSON.parse будет анонимным с помощью Framework.
Правильный синтаксис для безопасного превращения строки JSON в объект должен быть:

var object = JSON.decode(string[, secure]);

Кроме того, JSON Request может поднять объект, который может анализировать напрямую.
Вы можете cek как это сделать json сырые данные здесь:

http://jsfiddle.net/chetabahana/qbx9b5pm/

0

Более старый вопрос, я знаю, однако никто не замечает этого решения, используя 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

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

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

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

0

JS Guru Douglas Crockford написал функцию parseJSON, которую вы скачать здесь

Ещё вопросы

Сообщество Overcoder
Наверх
Меню