Десериализация JSON в объект JavaScript - PullRequest
240 голосов
/ 27 июня 2011

У меня есть строка в приложении сервера Java, доступ к которой осуществляется с помощью AJAX.Это выглядит примерно так:

var json = [{
    "adjacencies": [
        {
          "nodeTo": "graphnode2",
          "nodeFrom": "graphnode1",
          "data": {
            "$color": "#557EAA"
          }
        }
    ],
    "data": {
      "$color": "#EBB056",
      "$type": "triangle",
      "$dim": 9
    },
    "id": "graphnode1",
    "name": "graphnode1"
},{
    "adjacencies": [],
    "data": {
      "$color": "#EBB056",
      "$type": "triangle",
      "$dim": 9
    },
    "id": "graphnode2",
    "name": "graphnode2"
}];

Когда строка извлекается с сервера, есть ли простой способ превратить ее в живой объект JavaScript (или массив)?Или мне нужно вручную разбить строку и построить свой объект вручную?

Ответы [ 8 ]

375 голосов
/ 27 июня 2011

Современные браузеры поддерживают JSON.parse().

var arr_from_json = JSON.parse( json_string );

В браузерах, которые этого не делают, вы можете включить библиотеку json2 .

24 голосов
/ 27 июня 2011

Смысл JSON в том, что строки JSON могут быть преобразованы в собственные объекты без каких-либо действий.Проверьте эту ссылку

Вы можете использовать eval(string) или JSON.parse(string).

Однако, eval рискованно.От json.org:

Функция eval очень быстрая.Однако он может компилировать и выполнять любую программу JavaScript, поэтому могут возникнуть проблемы с безопасностью.Использование eval указывается, когда источник является доверенным и компетентным.Гораздо безопаснее использовать анализатор JSON.В веб-приложениях через XMLHttpRequest общение разрешено только с тем же источником, который предоставляет эту страницу, поэтому он является доверенным.Но это может быть не компетентно.Если сервер не является строгим в своей кодировке JSON или не тщательно проверяет все свои входные данные, то он может доставить недопустимый текст JSON, который может содержать опасный сценарий.Функция eval будет выполнять скрипт, раскрывая его злобу.

15 голосов
/ 27 июня 2011

Делай, как делает jQuery!(сущность)

function parseJSON(data) {
    return window.JSON && window.JSON.parse ? window.JSON.parse( data ) : (new Function("return " + data))(); 
}
// testing
obj = parseJSON('{"name":"John"}');
alert(obj.name);

Таким образом, вам не нужна никакая внешняя библиотека, и она все еще работает в старых браузерах.

7 голосов
/ 12 сентября 2013

Чтобы собрать все элементы массива и вернуть объект json

collectData: function (arrayElements) {

        var main = [];

        for (var i = 0; i < arrayElements.length; i++) {
            var data = {};
            this.e = arrayElements[i];            
            data.text = arrayElements[i].text;
            data.val = arrayElements[i].value;
            main[i] = data;
        }
        return main;
    },

Чтобы проанализировать те же данные, которые мы проходим, вот так

dummyParse: function (json) {       
        var o = JSON.parse(json); //conerted the string into JSON object        
        $.each(o, function () {
            inner = this;
            $.each(inner, function (index) {
                alert(this.text)
            });
        });

}
3 голосов
/ 21 января 2017

Вы также можете использовать eval(), но JSON.parse() более безопасный и простой способ, так почему бы вам?

хорошо и работает

var yourJsonObject = JSON.parse(json_as_text);

Я не вижу причин, по которым вы бы предпочли использовать eval. Это только подвергает вашу заявку риску.

Тем не менее - это возможно также возможно.

плохо - но тоже работает

var yourJsonObject = eval(json_as_text);

Почему eval плохая идея?

Рассмотрим следующий пример.

Некоторые сторонние или пользовательские данные предоставили строковые данные JSON.

var json = `
[{
    "adjacencies": [
        {
          "nodeTo": function(){
            return "delete server files - you have been hacked!";
          }(),
          "nodeFrom": "graphnode1",
          "data": {
            "$color": "#557EAA"
          }
        }
    ],
    "data": {
      "$color": "#EBB056",
      "$type": "triangle",
      "$dim": 9
    },
    "id": "graphnode1",
    "name": "graphnode1"
},{
    "adjacencies": [],
    "data": {
      "$color": "#EBB056",
      "$type": "triangle",
      "$dim": 9
    },
    "id": "graphnode2",
    "name": "graphnode2"
}]
`;

Ваш серверный скрипт обрабатывает эти данные.

Использование JSON.parse:

window.onload = function(){
  var placeholder = document.getElementById('placeholder1');
  placeholder.innerHTML = JSON.parse(json)[0].adjacencies[0].nodeTo;
}

бросит:

Uncaught SyntaxError: Unexpected token u in JSON at position X. 

Функция не будет выполнена.

Вы в безопасности.

Использование eval():

window.onload = function(){
  var placeholder = document.getElementById('placeholder1');
  placeholder.innerHTML = eval(json)[0].adjacencies[0].nodeTo;
}

выполнит функцию и вернет текст.

Если я заменю эту безвредную функцию на функцию, которая удаляет файлы из папки вашего сайта, вы были взломаны. В этом примере не будут выдаваться ошибки / предупреждения.

Вы НЕ в безопасности.

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

eval(JSON)[0].adjacencies[0].nodeTo ожидает обработки строки JSON, но на самом деле мы только что выполнили функцию на нашем сервере.

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

1 голос
/ 07 сентября 2015

И если вы также хотите, чтобы десериализованный объект имел функции, вы можете использовать мой маленький инструмент: https://github.com/khayll/jsmix

//first you'll need to define your model
var GraphNode = function() {};
GraphNode.prototype.getType = function() {
   return this.$type;
}

var Adjacency = function() {};
Adjacency.prototype.getData =n function() {
    return this.data;
}

//then you could say:
var result = JSMix(jsonData)
    .withObject(GraphNode.prototype, "*")
    .withObject(Adjacency.prototype, "*.adjacencies")
    .build();

//and use them
console.log(result[1][0].getData());
0 голосов
/ 04 февраля 2016

Я думаю, что это должно помочь:

Также документация также доказывает, что вы можете использовать require () для файлов json: https://www.bennadel.com/blog/2908-you-can-use-require-to-load-json-javascript-object-notation-files-in-node-js.htm

var jsonfile = require("./path/to/jsonfile.json");
node = jsonfile.adjacencies.nodeTo;
node2 = jsonfile.adjacencies.nodeFrom;
node3 = jsonfile.adjacencies.data.$color;
//other things.
0 голосов
/ 20 июня 2013

Если вы вставляете строку на стороне сервера в html, вам не нужно ничего делать:

Для простой Java в JSP:

var jsonObj=<%=jsonStringInJavaServlet%>;

Для распорок ширины JSP:

var jsonObj=<s:property value="jsonStringInJavaServlet" escape="false" escapeHtml="false"/>;
...