Deserialisieren eines JSON in ein JavaScript-Objekt

266

Ich habe eine Zeichenfolge in einer Java-Serveranwendung, auf die über AJAX zugegriffen wird. Es sieht ungefähr so ​​aus:

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

Gibt es eine einfache Möglichkeit, die Zeichenfolge vom Server in ein lebendes JavaScript-Objekt (oder Array) umzuwandeln, wenn sie vom Server abgerufen wird? Oder muss ich die Zeichenfolge manuell teilen und mein Objekt manuell erstellen?

mj_
quelle
mögliches Duplikat, wie man json in Javascript analysiert
Felix Kling
Mögliches Duplikat von Parse JSON in JavaScript?
m93a

Antworten:

397

Unterstützung für moderne Browser JSON.parse().

var arr_from_json = JSON.parse( json_string );

In Browsern, die dies nicht tun, können Sie die json2Bibliothek einschließen .

user113716
quelle
Wie funktioniert das für Datumsfelder in JSON, zum Beispiel {StartDate: "\ / Date (1372575600000) \ /"}?
Philipp Munin
@PhilippMunin Sie können diese Datumsfunktion über die Javascript-API verwenden: new Date (parseInt ("/ Date (946681200000) /". Replace ('/ Date (', '')))
Leo
oder Map () Objekte usw., wie macht man die richtige Deserialisierung
Ewan
25

Der springende Punkt bei JSON ist, dass JSON-Zeichenfolgen in native Objekte konvertiert werden können, ohne etwas zu tun. Überprüfen Sie dies Link

Sie können entweder eval(string)oder verwendenJSON.parse(string) .

Ist evaljedoch riskant. Von json.org:

Die Auswertungsfunktion ist sehr schnell. Es kann jedoch jedes JavaScript-Programm kompilieren und ausführen, sodass Sicherheitsprobleme auftreten können. Die Verwendung von eval wird angezeigt, wenn die Quelle vertrauenswürdig und kompetent ist. Es ist viel sicherer, einen JSON-Parser zu verwenden. In Webanwendungen über XMLHttpRequest ist die Kommunikation nur mit demselben Ursprung zulässig, der diese Seite bereitstellt, sodass sie vertrauenswürdig ist. Aber es könnte nicht kompetent sein. Wenn der Server in seiner JSON-Codierung nicht streng ist oder wenn er nicht alle Eingaben gewissenhaft überprüft, kann er ungültigen JSON-Text liefern, der möglicherweise gefährliche Skripte enthält. Die Auswertungsfunktion würde das Skript ausführen und seine Bosheit auslösen.

Abhinav
quelle
1
Ich verstehe das Risiko nicht. Kann niemand einen js-Debugger verwenden, um ein beliebiges Skript einzufügen und auszuführen?
xr280xr
3
@ xr280xr Ja, aber das passiert nur lokal in ihrem Browser, nicht in jedem Browser, der die Website herunterlädt.
Masterxilo
16

Machen Sie es wie jQuery! (die Essenz)

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

Auf diese Weise benötigen Sie keine externe Bibliothek und es funktioniert immer noch in alten Browsern.

Ravan Scafi
quelle
7
Dies sieht so aus, als würde es auf das Äquivalent von zurückfallen eval().
LarsH
1
Das ist gefährlich, eval ist böse!
Caesarsol
8

Um alle Elemente eines Arrays zu sammeln und ein JSON-Objekt zurückzugeben

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;
    },

Um die gleichen Daten zu analysieren, gehen wir so durch

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

}
Tarun Gupta
quelle
4

Sie könnten auch verwenden eval(), JSON.parse()ist aber sicherer und einfacher. Warum sollten Sie das tun?

gut und funktioniert

var yourJsonObject = JSON.parse(json_as_text);

Ich sehe keinen Grund, warum Sie es vorziehen würden, zu verwenden eval. Dies gefährdet nur Ihre Anwendung.

Das heißt - das ist auch möglich.

schlecht - funktioniert aber auch

var yourJsonObject = eval(json_as_text);

Warum ist evaleine schlechte Idee?

Betrachten Sie das folgende Beispiel.

Einige Drittanbieter oder Benutzer haben JSON-Zeichenfolgendaten bereitgestellt.

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

Ihr serverseitiges Skript verarbeitet diese Daten.

Verwenden von JSON.parse:

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

wird werfen:

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

Funktion wird nicht ausgeführt.

Du bist sicher.

Verwenden von eval():

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

führt die Funktion aus und gibt den Text zurück.

Wenn ich diese harmlose Funktion durch eine ersetze, die Dateien aus Ihrem Website-Ordner entfernt, wurden Sie gehackt. In diesem Beispiel werden keine Fehler / Warnungen ausgegeben.

Du bist NICHT sicher.

Ich konnte eine JSON-Textzeichenfolge so bearbeiten, dass sie als Funktion fungiert, die auf dem Server ausgeführt wird.

eval(JSON)[0].adjacencies[0].nodeTo erwartet, eine JSON-Zeichenfolge zu verarbeiten, aber in Wirklichkeit haben wir gerade eine Funktion auf unserem Server ausgeführt.

Dies könnte auch verhindert werden, wenn wir alle vom Benutzer bereitgestellten Daten serverseitig überprüfen, bevor wir sie an eine eval()Funktion übergeben. Warum jedoch nicht einfach das integrierte Tool zum Parsen von JSON verwenden und all diese Probleme und Gefahren vermeiden?

DevWL
quelle
1

Und wenn Sie auch möchten, dass das deserialisierte Objekt Funktionen hat, können Sie mein kleines Tool verwenden: 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
quelle
0

Wenn Sie die Zeichenfolge serverseitig in den HTML-Code einfügen, müssen Sie nichts tun:

Für einfaches Java in jsp:

var jsonObj=<%=jsonStringInJavaServlet%>;

Für JSP-Breitenstreben:

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