126 votes

Meilleur moyen de stocker JSON dans un attribut HTML?

J'ai besoin de mettre un objet JSON dans un attribut sur un élément HTML. Disons que c'est un <div> (il n'a pas d'importance). Voici quelques remarques importantes:

  1. Le HTML ne permet pas de valider.
  2. L'objet JSON pourrait être n'importe quelle taille (c'est à dire énorme).
  3. Que faire si le JSON contient des caractères spéciaux? (par exemple, {test: '<"myString/>'})
  4. J'ai besoin d'être en mesure d'écrire JSON dans le code HTML à l'aide de PHP sur la page de la charge, et de façon dynamique avec JavaScript.

Le principal problème est que les caractères spéciaux qui pourraient briser le code HTML. Donc, si j'avais un attribut comme ceci:

<div json="{test:'<"myString/>'}"> TESTING </div>

Quelle est la meilleure façon d'encoder au format JSON afin de ne pas casser quoi que ce soit?

EDIT DE PROGRÈS À CE JOUR:

Dans mon PHP, j'construire la balise HTML comme ceci:

<div id="mydiv" data-json="
    <?php echo htmlentities(json_encode($dataArray)) ?>
"> TESTING </div>

Tout semble bon dans le code HTML, comme prévu. Caractères spéciaux échappé.

Ensuite dans mon jQuery, comment puis-je les récupérer et de l'évaluer comme un objet nouveau?

var data = $.parseJSON($(this).attr('data-json'));

Firebug Erreur: JSON.parse:: nom de la propriété ou '}'

Si je puis changer le JSON et souhaitez écrire à l'aide de jQuery, je peux juste écrire de nouveau normalement sans codage bonne à rien? Ne qui fonctionnent vraiment?

45voto

Quentin Points 325526

Le HTML n'a pas à valider.

Pourquoi pas? La Validation est vraiment facile d'AQ qui attire beaucoup d'erreurs. Utilisation de HTML 5 data-* d'attribut.

L'objet JSON pourrait être n'importe quelle taille (c'est à dire énorme).

Je n'ai pas vu toute la documentation sur navigateur limites de l'attribut tailles.

Si vous n'exécutez en eux, puis stocker les données dans un <script>. Définir un objet et élément de la carte ids les noms des propriétés de cet objet.

Que faire si le JSON contient des caractères spéciaux? (par exemple, {test: '<"myString/>'})

Il suffit de suivre les règles normales, y compris pour les données non fiables dans les valeurs d'attribut. Utiliser &amp; et &quot; (si vous êtes d'emballage de la valeur de l'attribut dans les guillemets) ou &#x27; (si vous êtes d'emballage de la valeur de l'attribut dans des guillemets simples).

Notez, cependant, que ce n'est pas JSON (qui exige que les noms de propriété d'être des chaînes et des cordes d'être séparés seulement avec les guillemets).

22voto

gobwas Points 185

Une autre façon de le faire est de placer les données json dans les balises <script> , mais pas avec type="text/javascript" , mais avec type="text/bootstrap" ou type="text/json" type , pour éviter l'exécution de javascript.

Ensuite, à un endroit de votre programme, vous pouvez le demander de la manière suivante:

 function getData(key) {
  try {
    return JSON.parse($('script[type="text/json"]#' + key).text());
  } catch (err) { // if we have not valid json or dont have it
    return null;
  } 
}
 

Du côté du serveur, vous pouvez faire quelque chose comme ceci (cet exemple avec php et twig ):

 <script id="my_model" type="text/json">
  {{ my_model|json_encode()|raw }}
</script>
 

17voto

Mike Samuel Points 54712

Selon l'endroit où vous le mettez,

  • En <div> comme vous l'avez demandé, vous devez vous assurer que le JSON ne contient pas de HTML spéciaux, qui pourrait débuter une étiquette, d'un commentaire HTML, incorporé doctype, etc. Vous avez besoin d'échapper, au moins, <, et & de telle manière que le caractère original n'apparaît pas dans l'échappé de la séquence.
  • En <script> éléments dont vous avez besoin pour s'assurer que le JSON ne contient pas de balise de fin </script> ou s'échapper de délimiteur de texte: <!-- ou -->.
  • Dans les gestionnaires d'événements, vous devez vous assurer que le JSON conserve son sens, même si il y a des choses qui ressemblent à des entités HTML et ne rompt pas l'attribut limites (" ou ').

Pour les deux premiers cas (et pour le vieux JSON analyseurs de), vous devez encoder U+2028 et U+2029 car ceux sont des caractères de saut de ligne en JavaScript, même s'ils sont autorisés dans les chaînes non codée en JSON.

Pour la correction, vous devez vous échapper \ et JSON, les guillemets et ce n'est jamais une mauvaise idée de toujours coder NUL.

Si le code HTML peut être servi sans un encodage du contenu, vous devez encoder + pour prévenir l'UTF-7 attaques.

En tout cas, la suite s'échapper table de travail:

  • NUL -> \u0000
  • CR -> \n ou \u000a
  • LF -> \r ou \u000d
  • " -> \u0022
  • & -> \u0026
  • ' -> \u0027
  • + -> \u002b
  • / -> \/ ou \u002f
  • < -> \u003c
  • > -> \u003e
  • \ -> \\ ou \u005c
  • U+2028 -> \u2028
  • U+2029 -> \u2029

Si la chaîne JSON de la valeur pour le texte Hello, <World>! avec un saut de ligne à la fin serait "Hello, \u003cWorld\u003e!\r\n".

5voto

jayM Points 251

Vous pouvez utiliser knockoutjs,

 <p>First name: <strong data-bind="text: firstName" >todo</strong></p>
<p>Last name: <strong data-bind="text: lastName">todo</strong></p>
 

knockout.js

 // This is a simple *viewmodel* - JavaScript that defines the data and behavior of your UI
function AppViewModel() {
    this.firstName = "Jayson";
    this.lastName = "Monterroso";
}

// Activates knockout.js
ko.applyBindings(new AppViewModel());
 

Sortie

Prénom: Jayson Nom: Monterroso

Vérifiez ceci: http://learn.knockoutjs.com/

2voto

Matchu Points 37755

Rien d'extraordinaire ici. Depuis PHP, exécutez htmlspecialchars sur la chaîne JSON pour vous assurer qu'aucun caractère spécial ne peut être interprété en tant que HTML. De Javascript, aucune évasion nécessaire; il suffit de définir l'attribut et vous êtes prêt à partir.

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