134 votes

Meilleure pratique pour intégrer un JSON arbitraire dans le DOM ?

Je pense à intégrer un JSON arbitraire dans le DOM comme ceci :

<script type="application/json" id="stuff">
    {
        "unicorns": "awesome",
        "abc": [1, 2, 3]
    }
</script>

C'est similaire à la façon dont on peut stocker un modèle HTML arbitraire dans le DOM pour une utilisation ultérieure avec un moteur de modèles JavaScript. Dans ce cas, nous pourrions plus tard récupérer le JSON et l'analyser avec :

var stuff = JSON.parse(document.getElementById('stuff').innerHTML);

Cela fonctionne mais est-ce le meilleur moyen ? Est-ce que cela viole une norme ou une meilleure pratique ?

Note : Je ne cherche pas d'alternatives au stockage de JSON dans le DOM, j'ai déjà décidé que c'était la meilleure solution pour le problème particulier que je rencontre. Je cherche simplement la meilleure façon de le faire.

2 votes

Pourquoi ne pas l'avoir en tant que var en javascript ?

0 votes

@Krizz, il doit faire partie d'un document statique qui est ensuite traité par une chaîne complexe de javascript encapsulé. Le stocker dans le DOM est ce que je veux faire.

0 votes

@Krizz On m'a posé un problème similaire. Je voulais mettre des 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 conteneur et fait quelque chose de similaire à ce que vous avez ci-dessus pour obtenir les données en javascript.

90voto

Jamie Treworgy Points 13495

Je pense que votre méthode est la meilleure. La spec HTML5, même les adresses de cette utilisation:

"Lorsqu'il est utilisé pour inclure des blocs de données (par opposition à des scripts), les données doit être incorporé en ligne, le format des données doit être donné à l'aide de l'attribut type de l'attribut src ne doit pas être spécifié, et le contenu de l'élément script doit être conforme aux exigences défini pour le format utilisé."

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.

3 votes

Merci. La citation de la spécification m'a convaincu.

18 votes

Cela n'est parfaitement valable que si vous vérifiez et assainissez d'abord l'objet JSON : vous ne pouvez pas simplement intégrer des données provenant de l'utilisateur. Voir mon commentaire sur la question.

1 votes

Une question supplémentaire : quel est le bon endroit pour le mettre ? tête ou corps, haut ou bas ?

21voto

Horatio Alderaan Points 1635

En règle générale, j'essaierais d'utiliser Attributs de données HTML5 à la place. Rien ne vous empêche de mettre du JSON valide, par exemple :

<div id="mydiv" data-unicorns='{"unicorns":"awesome", "abc":[1,2,3]}' class="hidden"></div>

Si vous utilisez jQuery, il suffit de le récupérer :

var stuff = JSON.parse($('#mydiv').attr('data-unicorns'));

1 votes

C'est logique. Cependant, notez qu'avec des guillemets simples pour le nom de la clé, JSON.parse ne fonctionnera pas (du moins pas avec la fonction native JSON.parse de Google Chrome). La spécification JSON exige des guillemets doubles. Mais c'est assez facile à corriger en utilisant des entités comme ...&lt;unicorns&gt;:... .

5 votes

Une question cependant : la longueur des attributs est-elle limitée dans le HTML 5 ?

0 votes

Oui, ça pourrait marcher. Vous pouvez aussi inverser les choses pour que votre HTML utilise des guillemets simples et les données JSON des guillemets doubles.

16voto

MadCoder Points 11

Cette méthode d'intégration de données json dans une balise script présente un problème de sécurité potentiel. En supposant que les données json proviennent de l'entrée de l'utilisateur, il est possible de créer un membre de données qui s'échappera de la balise script et permettra une injection directe dans le dom. Voir ici :

http://jsfiddle.net/YmhZv/1/

Voici l'injection

<script type="application/json" id="stuff">
{
    "unicorns": "awesome",
    "abc": [1, 2, 3],
    "badentry": "blah </script><div id='baddiv'>I should not exist.</div><script type="application/json" id='stuff'> ",
}
</script>

Il n'y a aucun moyen de contourner l'échappement/le codage.

9 votes

C'est vrai, mais ce n'est pas vraiment un défaut de sécurité de la méthode. Si vous mettez dans vos pages quelque chose qui provient de la saisie de l'utilisateur, vous devez faire preuve de diligence pour l'échapper. Cette méthode reste valable tant que vous prenez les mesures de précaution habituelles concernant la saisie par l'utilisateur.

0 votes

JSON ne fait pas partie du HTML, l'analyseur syntaxique du HTML continue. C'est la même chose que lorsque le JSON fait partie d'un paragraphe de texte ou d'un élément div. L'échappement HTML du contenu dans votre programme. En outre, vous pouvez également échapper aux barres obliques. Bien que JSON ne l'exige pas, il tolère les slashs inutiles. Ces dernières peuvent être utilisées dans le but de sécuriser l'intégration. La fonction json_encode de PHP le fait par défaut.

6voto

copy Points 2070

Je suggérerais de mettre JSON dans un script en ligne avec une fonction de rappel (sorte de JSONP ) :

<script>
someCallback({
    "unicorns": "awesome",
    "abc": [1, 2, 3]
});
</script>

Si le script d'exécution est chargé après le document, vous pouvez le stocker quelque part, éventuellement avec un argument identifiant supplémentaire : someCallback("stuff", { ... });

0 votes

@BenLee cela devrait très bien fonctionner, avec le seul inconvénient de devoir définir la fonction de rappel. L'autre solution proposée s'attaque aux caractères HTML spéciaux (par exemple &) et aux guillemets, si vous en avez dans votre JSON.

0 votes

C'est mieux car vous n'avez pas besoin d'une requête dom pour trouver les données.

0 votes

@copy Cette solution nécessite toujours un échappement (d'un type différent), voir la réponse de MadCoder. Je la laisse ici par souci d'exhaustivité.

1voto

Šime Vidas Points 59994

Je recommande de conserver les données JSON dans des fichiers externes. .json et ensuite récupérer ces fichiers via Ajax. Vous ne mettez pas le code CSS et JavaScript sur la page web (en ligne), alors pourquoi le feriez-vous avec JSON ?

16 votes

On ne met pas de CSS et de Javascript en ligne dans une page Web, car ils sont généralement partagés entre d'autres pages. Si les données en question sont générées par le serveur explicitement pour ce contexte, les intégrer est bien plus efficace que d'initier une autre requête pour quelque chose qui ne peut être mis en cache.

0 votes

C'est parce que je fais des mises à jour d'un ancien système qui a été mal conçu, et plutôt que de reconcevoir l'ensemble du système, je dois juste en corriger une partie. Le stockage de JSON dans le DOM est le meilleur moyen de corriger cette partie. Aussi, je suis d'accord avec ce que @jamietre a dit.

0 votes

@jamietre Notez que le PO a déclaré que cette chaîne JSON est seulement nécessaire plus tard . La question est de savoir si elle est nécessaire en permanence, ou seulement dans certains cas. S'il n'est nécessaire que dans certains cas, alors il est logique de le placer dans un fichier externe et de ne le charger que de manière conditionnelle.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X