Désérialisation d'un JSON en un objet JavaScript


266

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

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 (ou tableau) JavaScript vivant? Ou dois-je diviser manuellement la chaîne et créer mon objet manuellement?



Copie possible de Parse JSON en JavaScript?
m93a

Réponses:


397

Prise en charge des navigateurs modernes JSON.parse().

var arr_from_json = JSON.parse( json_string );

Dans les navigateurs qui ne le font pas, vous pouvez inclure la json2bibliothèque .


Comment cela fonctionnera-t-il pour les champs de date dans JSON, par exemple {StartDate: "\ / Date (1372575600000) \ /"}?
Philipp Munin

@PhilippMunin vous pouvez utiliser cette fonction Date à partir de l'API javascript: new Date (parseInt ("/ Date (946681200000) /". Replace ('/ Date (', '')));
Leo

ou des objets Map (), etc., comment procéder à une désérialisation appropriée
Ewan

25

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

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

Cependant, evalc'est risqué. De json.org:

La fonction eval est très rapide. Cependant, il peut compiler et exécuter n'importe quel programme JavaScript, il peut donc y avoir des problèmes de sécurité. L'utilisation d'eval est indiquée lorsque la source est fiable et compétente. Il est beaucoup plus sûr d'utiliser un analyseur JSON. Dans les applications Web via XMLHttpRequest, la communication n'est autorisée que vers la même origine qui fournit cette page, elle est donc approuvée. Mais il pourrait ne pas être compétent. Si le serveur n'est pas rigoureux dans son encodage JSON, ou s'il ne valide pas scrupuleusement toutes ses entrées, alors il pourrait fournir un texte JSON invalide qui pourrait être porteur d'un script dangereux. La fonction eval exécuterait le script, déclenchant sa malveillance.


1
Je ne comprends pas le risque. Est-ce que personne ne peut utiliser un débogueur js pour injecter et exécuter le script de son choix?
xr280xr

3
@ xr280xr Oui, mais cela ne se produit que localement dans leur navigateur, pas dans tous les navigateurs qui téléchargent le site Web.
masterxilo

16

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 pas besoin de bibliothèque externe et cela fonctionne toujours sur les anciens navigateurs.


7
On dirait qu'il revient à l'équivalent de eval().
LarsH

1
C'est dangereux, l'eval est mauvais!
caesarsol

8

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

Pour analyser les mêmes données que nous traversons comme ça

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

Vous pouvez également utiliser eval()mais JSON.parse()c'est 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 pourquoi préféreriez-vous utiliser eval. Cela ne fait que mettre votre application en danger.

Cela dit - c'est également possible.

mauvais - mais fonctionne aussi

var yourJsonObject = eval(json_as_text);

Pourquoi est-ce evalune mauvaise idée?

Prenons l'exemple suivant.

Un tiers ou un utilisateur a 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.

En utilisant 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.

Tu es en sécurité.

En utilisant 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 qui supprime les fichiers de votre dossier de site Web, vous avez été piraté. Aucune erreur / avertissement ne sera généré dans cet exemple.

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

J'ai pu manipuler une chaîne de texte JSON pour 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 eval()fonction, mais pourquoi ne pas simplement utiliser l'outil intégré pour analyser JSON et éviter tous ces problèmes et dangers?


1

Et si vous souhaitez également 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());

0

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

Pour Java simple en JSP:

var jsonObj=<%=jsonStringInJavaServlet%>;

Pour les entretoises de largeur jsp:

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.