Десеріалізація 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 (або масив)? Або мені потрібно вручну розділити рядок і скласти об’єкт вручну?


можливий дублікат того, як розібрати json у javascript
Фелікс Клінг

Можливий дублікат Parse JSON в JavaScript?
m93a

Відповіді:


397

Сучасні браузери підтримують JSON.parse().

var arr_from_json = JSON.parse( json_string );

У браузерах , які не роблять, ви можете включити в json2бібліотеку .


Як це буде працювати для полів дати у JSON, наприклад {StartDate: "\ / Date (1372575600000) \ /"}?
Філіп Мунін

@PhilippMunin ви можете використовувати цю функцію Date з API javascript: нова дата (parseInt ("/ дата (946681200000) /". Замінити ('/ Дата (', '')));
Лев,

або об’єкти Map () тощо, як зробити правильну десеріалізацію
Ewan

25

Вся суть JSON в тому, що струни JSON можна перетворити на рідні об'єкти, не роблячи нічого. Перевірте це посилання

Ви можете використовувати eval(string)або JSON.parse(string).

Однак evalце ризиковано. Від json.org:

Функція eval дуже швидка. Однак він може компілювати та виконувати будь-яку програму JavaScript, тому можуть виникнути проблеми із безпекою. Використання eval вказується, коли джерелу довіряють та грамотно. Набагато безпечніше використовувати аналізатор JSON. У веб-додатках, що надходять через XMLHttpRequest, дозволено спілкування лише того самого джерела, що і ця сторінка, і тому йому довіряють. Але це може бути не компетентним. Якщо сервер не є суворим у кодуванні JSON або якщо він не ретельно перевіряє всі свої входи, то він може доставити недійсний текст JSON, який може містити небезпечний сценарій. Функція eval виконує сценарій, розкриваючи його злобу.


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

TO зібрати весь елемент масиву і повернути об’єкт 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 та уникнути всіх цих проблем та небезпеки?


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

0

Якщо ви вставите рядок на стороні сервера в html, нічого не потрібно робити:

Для звичайної Java в jsp:

var jsonObj=<%=jsonStringInJavaServlet%>;

Для розширень jsp:

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

-3

Я думаю, що це повинно допомогти:

Також документація також доводить, що ви можете використовувати потребує () для файлів 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.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.