Les meilleures pratiques pour l'intégration arbitraire JSON dans les DOM?
Je suis en train de penser à propos de l'incorporation de l'arbitraire JSON dans les DOM comme ceci:
<script type="application/json" id="stuff">
{
"unicorns": "awesome",
"abc": [1, 2, 3]
}
</script>
Ceci est similaire à la façon dont on peut stocker l'arbitraire d'un modèle HTML dans les DOM pour les utiliser plus tard avec un JavaScript moteur de template. Dans ce cas, on pourrait récupérer plus tard le JSON et analyser avec:
var stuff = JSON.parse(document.getElementById('stuff').innerHTML);
Cela fonctionne, mais est-ce la meilleure solution? Est-ce à violer toutes les meilleures pratiques ou standard?
Note: je ne suis pas à la recherche de solutions pour le stockage de JSON dans les DOM, j'ai déjà décidé que c'est la meilleure solution pour le problème que je vais avoir. Je suis en quête de la meilleure façon de le faire.
- pourquoi ne pas vous l'avoir comme
var
en javascript? - il doit faire partie d'un document statique, il est ensuite traité par une chaîne complexe de encapsulé javascript. De le ranger dans le DOM est ce que je veux faire.
- J'étais posé avec un problème similaire. Je voulais mettre les données dans un site différent pour chaque utilisateur sans faire une requête AJAX. J'ai donc intégré du PHP dans un récipient fait quelque chose de similaire à ce que vous avez ci-dessus pour obtenir les données en javascript.
- Je pense que votre méthode originale est le meilleur en fait. Il est 100% valide en HTML5, il est expressif, il ne veut pas créer de "faux" des éléments que vous venez de supprimer ou de masquer avec du CSS; et il ne nécessite pas de codage de caractères. Quel est l'inconvénient?
- Si vous avez une chaîne avec la valeur
</script><script>alert()</script><script>
à l'intérieur de votre objet JSON, vous aurez des surprises. Ce n'est pas sûr, à moins que vous désinfecter les données de la première. - si j'étais à l'aveuglette remplacer tout
<
dans la chaîne JSON avec\u003C
, serait-ce suffisant? Il semble trop simple pour vraiment travailler...
InformationsquelleAutor Ben Lee | 2012-02-16
Vous devez vous connecter pour publier un commentaire.
Je pense que votre méthode est la meilleure. La spec HTML5, même les adresses de cette utilisation:
Lire ici: http://dev.w3.org/html5/spec/Overview.html#the-script-element
Vous avez fait exactement cela. Ce n'est pas de l'amour? Pas de codage de caractères en tant que de besoin avec les données d'attribut. Vous pouvez mettre en forme si vous le souhaitez. C'est de l'expressivité et de l'utilisation prévue est clair. Il ne se sent pas comme un hack (par exemple à l'aide de CSS pour cacher votre "transporteur" élément n'). Il est parfaitement valide.
script
balises.Comme une direction générale, je voudrais essayer d'utiliser HTML5 attributs de données à la place. Il n'y a rien pour vous empêcher de vous mettre en JSON valide. par exemple:
Si vous utilisez jQuery, puis de la récupérer est aussi simple que:
JSON.parse
ne fonctionne pas (au moins le natif de Google Chrome JSON.analyser ne va pas). La spécification JSON nécessite des guillemets doubles. Mais cela est assez facile à fixer à l'aide des entités telles que les...<unicorns>:...
."I am valid JSON"
et en utilisant des guillemets doubles pour le tag, ou des guillemets simples avec des guillemets simples dans la chaîne, par exempledata-unicorns='"My JSON's string"'
que les apostrophes ne sont pas échappé à l'encodage JSON.escape(JSON.stringify({str: "'"}))
Cette méthode de l'intégration de json dans une balise script a un problème de sécurité potentiel. En supposant que les données json origine de la saisie de l'utilisateur, il est possible de fabriquer un membre de données qui va en effet sortir de la balise de script et de permettre l'injection directe dans les dom. Voir ici:
http://jsfiddle.net/YmhZv/1/
Ici est l'injection
Il n'y a juste pas moyen de contourner échapper/codage.
Je te suggère de mettre JSON dans un script en ligne avec une fonction de rappel (sorte de JSONP):
Si l'exécution du script est chargé après le document, vous pouvez stocker quelque part, peut-être avec un autre identificateur argument:
someCallback("stuff", { ... });
Voir Règle n ° 3.1 dans l'OWASP est XSS prévention de la feuille de triche.
Dites que vous voulez inclure ce JSON en HTML:
Créer un caché
<div>
en HTML. Ensuite, sortez de vos JSON par codage dangereux entités (par exemple, &, <, >, ",", et, /) et de le mettre à l'intérieur de l'élément.Vous pouvez maintenant accéder en lecture de la
textContent
de l'élément à l'aide de JavaScript et de l'analyser:{name: 'Dwayne "The Rock" Johnson'}
. Mais il est probablement préférable d'utiliser cette approche depuis votre cadre/template library probablement déjà inclut un moyen sûr de faire le codage HTML. Une alternative serait d'utiliser base64 qui est à la fois HTML sûr et sécuritaire à l'intérieur d'un JS chaîne. Il est facile de coder/décoder en JS en utilisant btoa()/atob() et il est probablement plus facile pour vous de le faire côté serveur.<data>
élément et inclure les données JSON dans levalue
attribut. Ensuite, vous avez seulement besoin d'échapper les guillemets avec"
si vous utilisez des guillemets pour entourer les données, ou'
si vous utilisez des guillemets simples (ce qui est probablement mieux).Ma recommandation serait de garder les données JSON en externe
.json
fichiers, et ensuite récupérer les fichiers via Ajax. Vous ne mettez pas de CSS et le code JavaScript sur la page web (inline), alors pourquoi voudriez-vous le faire avec JSON?HTML5 comprend un
<données>
de l'élément pour garder des données lisibles par machine. Comme—peut-être plus sure—pour<script type="application/json">
vous pouvez inclure vos données JSON à l'intérieur de lavalue
attribut de l'élément.JS:
HTML:
Dans ce cas, vous devez remplacer tous les guillemets simples avec
'
ou avec"
si vous optez pour placer la valeur entre guillemets. Sinon, votre risque XSS attaques, comme les autres réponses ont suggéré.