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?
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
.
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.
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.
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)
});
});
}
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?
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());
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"/>;