Удаление десериализации JSON в объект JavaScript

У меня есть строка в приложении сервера 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? Или мне нужно вручную разбить строку и построить мой объект вручную?

Ответ 1

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

var arr_from_json = JSON.parse( json_string );

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

Ответ 2

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

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

Однако eval является рискованным. От json.org:

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

Ответ 3

Похоже на 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);

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

Ответ 4

Чтобы собрать весь элемент массива и вернуть объект 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)
            });
        });

}

Ответ 5

Вы также можете использовать 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"
}]
`;

Ваша серверная сторона script обрабатывает эти данные.

Использование 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 и избежать всех этих проблем и опасности?

Ответ 6

И если вы также хотите, чтобы десериализованный объект имел функции, вы могли бы использовать мой небольшой инструмент: 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());

Ответ 7

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

Для простой java в jsp:

var jsonObj=<%=jsonStringInJavaServlet%>;

Для расположений ширины jsp:

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

Ответ 8

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

Также документация также доказывает, что вы можете использовать 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.