web-dev-qa-db-fra.com

Désérialiser un JSON dans un objet JavaScript

J'ai une chaîne dans une application serveur Java accessible via AJAX. Cela ressemble à ce qui suit:

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

Lorsque la chaîne est extraite du serveur, existe-t-il un moyen simple de transformer cela en un objet JavaScript (ou un tableau) vivant? Ou dois-je fractionner manuellement la chaîne et construire mon objet manuellement?

243
mj_

Les navigateurs modernes supportent JSON.parse().

var arr_from_json = JSON.parse( json_string );

Dans les autres navigateurs, vous pouvez inclure la bibliothèque json2 .

379
user113716

L'intérêt de JSON est que les chaînes JSON peuvent être converties en objets natifs sans rien faire. Vérifiez ceci lien

Vous pouvez utiliser eval(string) ou JSON.parse(string).

Cependant, eval est risqué. De json.org:

La fonction eval est très rapide. Cependant, il peut compiler et exécuter n'importe quel programme JavaScript, ce qui peut poser des problèmes de sécurité. L'utilisation de eval est indiquée lorsque la source est fiable et compétente. Il est beaucoup plus prudent d'utiliser un analyseur JSON. Dans les applications Web utilisant XMLHttpRequest, la communication est autorisée uniquement avec la même origine que celle qui fournit cette page, elle est donc sécurisée. Mais cela pourrait ne pas être compétent. Si le codage JSON du serveur n'est pas rigoureux, ou s'il ne valide pas scrupuleusement toutes ses entrées, il pourrait alors fournir un texte JSON non valide pouvant contenir un script dangereux. La fonction eval exécuterait le script, libérant ainsi sa malveillance.

24
Abhinav

Faites comme jQuery! (l'essence)

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

De cette façon, vous n'avez besoin d'aucune bibliothèque externe et cela fonctionne toujours sur les anciens navigateurs.

15
Ravan Scafi

TO collecter tous les éléments d'un tableau et retourner un objet 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;
    },

Analyser les mêmes données que nous traversons comme ceci

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

}
8
Tarun Gupta

Vous pouvez également utiliser eval() mais JSON.parse() est un moyen plus sûr et plus simple, alors pourquoi le feriez-vous?

bon et fonctionne

var yourJsonObject = JSON.parse(json_as_text);

Je ne vois aucune raison pour laquelle préféreriez-vous utiliser eval. Cela ne fait que mettre votre application en danger.

Cela dit - ceci est également possible.

mauvais - mais ça marche aussi

var yourJsonObject = eval(json_as_text);

Pourquoi eval est-il une mauvaise idée?

Prenons l'exemple suivant.

Certains tiers ou utilisateurs ont fourni des données de chaîne 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"
}]
`;

Votre script côté serveur traite ces données.

tilisation de JSON.parse:

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

jettera:

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

La fonction ne sera pas exécutée.

Vous êtes en sécurité.

tilisation de eval():

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

exécutera la fonction et renverra le texte.

Si je remplace cette fonction inoffensive par une autre qui supprime les fichiers du dossier de votre site Web, vous êtes piraté. Aucune erreur/avertissement ne sera généré dans cet exemple.

Vous n'êtes pas en sécurité.

J'ai été en mesure de manipuler une chaîne de texte JSON afin qu'elle agisse comme une fonction qui s'exécutera sur le serveur.

eval(JSON)[0].adjacencies[0].nodeTo s'attend à traiter une chaîne JSON mais, en réalité, nous venons d'exécuter une fonction sur notre serveur.

Cela pourrait également être évité si nous vérifions côté serveur toutes les données fournies par l'utilisateur avant de les transmettre à une fonction eval(), mais pourquoi ne pas utiliser simplement l'outil intégré d'analyse de JSON et éviter tout problème ou danger?

3
DevWL

Et si vous voulez aussi que l'objet désérialisé ait des fonctions, vous pouvez utiliser mon petit outil: 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());
1
fishgen

Si vous collez la chaîne côté serveur dans le code HTML, vous n'avez rien à faire:

Pour le type Java dans jsp:

var jsonObj=<%=jsonStringInJavaServlet%>;

Pour les entretoises de largeur jsp:

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