Десериализация JSON в объект JavaScript

266

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

mj_
источник
возможный дубликат того, как разобрать JSON в JavaScript
Феликс Клинг
Возможная копия Parse JSON в JavaScript?
m93a

Ответы:

397

Поддержка современных браузеров JSON.parse().

var arr_from_json = JSON.parse( json_string );

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

user113716
источник
Как это будет работать для полей даты в JSON, например {StartDate: "\ / Date (1372575600000) \ /"}?
Филипп Мунин
@PhilippMunin вы можете использовать эту функцию Date из API javascript: new Date (parseInt ("/ Date (946681200000) /". Replace ('/ Date (', '')));
Лев
или Map () объекты и т. д., как вы делаете правильную десериализацию
Ewan
25

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

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

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

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

Abhinav
источник
1
Я не понимаю риск. Никто не может использовать отладчик js для внедрения и выполнения любого сценария, который они хотят?
xr280xr
3
@ xr280xr Да, но это происходит только локально в их браузере, а не в каждом браузере, который загружает сайт.
masterxilo
16

Делай как 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
Похоже, что это отступает к эквиваленту eval().
LarsH
1
Это опасно, Эвал - это зло!
Цезарсол
8

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

}
Тарун Гупта
источник
4

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

DevWL
источник
1

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

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

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

var jsonObj=<%=jsonStringInJavaServlet%>;

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

var jsonObj=<s:property value="jsonStringInJavaServlet" escape="false" escapeHtml="false"/>;
surfealokesea
источник
-3

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

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

var jsonfile = require("./path/to/jsonfile.json");
node = jsonfile.adjacencies.nodeTo;
node2 = jsonfile.adjacencies.nodeFrom;
node3 = jsonfile.adjacencies.data.$color;
//other things.
PSXGamerPro1
источник