Deserializzare un JSON in un oggetto JavaScript


266

Ho una stringa in un'applicazione server Java a cui si accede tramite AJAX. È simile al seguente:

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"
}];

Quando la stringa viene estratta dal server, c'è un modo semplice per trasformarla in un oggetto (o matrice) JavaScript vivente? O devo dividere manualmente la stringa e costruire il mio oggetto manualmente?



Possibile duplicato di Parse JSON in JavaScript?
m93a,

Risposte:


397

Supporto per browser moderni JSON.parse().

var arr_from_json = JSON.parse( json_string );

Nei browser che non lo fanno, puoi includere la json2libreria .


Come funzionerà per i campi data in JSON, ad esempio {StartDate: "\ / Date (1372575600000) \ /"}?
Philipp Munin,

@PhilippMunin potresti usare questa funzione Date dall'API javascript: new Date (parseInt ("/ Date (946681200000) /". Replace ('/ Date (', '')));
Leo

o oggetti Map () ecc., come si fa a deserializzare correttamente
Ewan

25

Il punto centrale di JSON è che le stringhe JSON possono essere convertite in oggetti nativi senza fare nulla. Controlla questo link

Puoi usare eval(string)o JSON.parse(string).

Tuttavia, evalè rischioso. Da json.org:

La funzione eval è molto veloce. Tuttavia, può compilare ed eseguire qualsiasi programma JavaScript, quindi possono esserci problemi di sicurezza. L'uso di eval è indicato quando la fonte è attendibile e competente. È molto più sicuro utilizzare un parser JSON. Nelle applicazioni Web su XMLHttpRequest, la comunicazione è consentita solo alla stessa origine che fornisce quella pagina, quindi è attendibile. Ma potrebbe non essere competente. Se il server non è rigoroso nella sua codifica JSON o se non convalida scrupolosamente tutti i suoi input, potrebbe fornire un testo JSON non valido che potrebbe contenere script pericolosi. La funzione eval avrebbe eseguito lo script, scatenando la sua malizia.


1
Non capisco il rischio. Qualcuno non può usare un debugger js per iniettare ed eseguire lo script che vogliono comunque?
xr280xr,

3
@ xr280xr Sì, ma ciò accade solo localmente nel browser, non in tutti i browser che scaricano il sito Web.
masterxilo,

16

Fai come jQuery! (l'essenza)

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

In questo modo non hai bisogno di alcuna libreria esterna e funziona ancora su vecchi browser.


7
Sembra che stia tornando all'equivalente di eval().
LarsH,

1
Questo è pericoloso, eval è malvagio!
caesarsol,

8

PER raccogliere tutti gli elementi di un array e restituire un oggetto 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;
    },

PER analizzare gli stessi dati che analizziamo in questo modo

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

Potresti anche usare eval()ma JSON.parse()è un modo più sicuro e semplice, quindi perché dovresti?

bene e funziona

var yourJsonObject = JSON.parse(json_as_text);

Non vedo alcun motivo per cui preferiresti usare eval. Mette a rischio la tua applicazione.

Detto questo, anche questo è possibile.

male - ma funziona anche

var yourJsonObject = eval(json_as_text);

Perché è evaluna cattiva idea?

Considera il seguente esempio.

Alcuni dati di stringa JSON forniti da terze parti o utenti.

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"
}]
`;

Lo script sul lato server elabora tali dati.

Utilizzando JSON.parse:

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

getterà:

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

La funzione non verrà eseguita.

Sei al sicuro.

Utilizzando eval():

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

eseguirà la funzione e restituirà il testo.

Se sostituisco quella funzione innocua con una che rimuove i file dalla cartella del tuo sito Web, sei stato violato. In questo esempio non verranno generati errori / avvisi.

NON sei al sicuro.

Sono stato in grado di manipolare una stringa di testo JSON in modo che agisca come una funzione che verrà eseguita sul server.

eval(JSON)[0].adjacencies[0].nodeTo si aspetta di elaborare una stringa JSON ma, in realtà, abbiamo appena eseguito una funzione sul nostro server.

Ciò potrebbe anche essere evitato se sul lato server controlliamo tutti i dati forniti dall'utente prima di passarli a una eval()funzione, ma perché non usare semplicemente lo strumento integrato per analizzare JSON ed evitare tutti questi problemi e pericoli?


1

E se vuoi che anche l'oggetto deserializzato abbia delle funzioni, potresti usare il mio piccolo strumento: 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

Se si incolla la stringa sul lato server in HTML non è necessario fare nulla:

Per java semplice in jsp:

var jsonObj=<%=jsonStringInJavaServlet%>;

Per puntoni con larghezza jsp:

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.