214 votes

Élimination des entités HTML en JavaScript ?

J'ai un code JavaScript qui communique avec un backend XML-RPC. Le XML-RPC renvoie des chaînes de la forme :

<img src='myimage.jpg'>

Cependant, lorsque j'utilise le JavaScript pour insérer les chaînes dans le HTML, elles s'affichent littéralement. Je ne vois pas une image, je vois littéralement la chaîne :

<img src='myimage.jpg'>

Je pense que le HTML est échappé par le canal XML-RPC.

Comment décompresser une chaîne de caractères en JavaScript ? J'ai essayé les techniques présentées sur cette page, sans succès : http://paulschreiber.com/blog/2008/09/20/javascript-how-to-unescape-html-entities/

Quels sont les autres moyens de diagnostiquer le problème ?

195voto

CMS Points 315406

EDIT : Vous devez utiliser l'API DOMParser comme Wladimir suggère J'ai modifié ma réponse précédente car la fonction affichée présentait une faille de sécurité.

L'extrait suivant est le code de l'ancienne réponse avec une petite modification : l'utilisation d'un fichier textarea au lieu d'un div réduit la vulnérabilité XSS, mais elle reste problématique dans IE9 et Firefox.

function htmlDecode(input){
  var e = document.createElement('textarea');
  e.innerHTML = input;
  // handle case of empty input
  return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}

htmlDecode("&lt;img src='myimage.jpg'&gt;"); 
// returns "<img src='myimage.jpg'>"

En fait, je crée un élément DOM par programme, j'assigne le code HTML à son innerHTML et je récupère la valeur du nœud à partir du nœud texte créé lors de l'insertion de l'innerHTML. Comme il s'agit simplement de créer un élément mais jamais de l'ajouter, le code HTML du site n'est pas modifié.

Il fonctionnera avec tous les navigateurs (y compris les plus anciens) et acceptera tous les Entités de caractères HTML .

EDIT : L'ancienne version de ce code ne fonctionnait pas sur IE avec des entrées vides, comme le montre l'exemple suivant ici sur jsFiddle (voir dans IE). La version ci-dessus fonctionne avec toutes les entrées.

MISE À JOUR : il semble que cela ne fonctionne pas avec les grandes chaînes de caractères, et cela introduit également une erreur de type vulnérabilité de la sécurité Voir les commentaires.

0 votes

J'ai compris, vous avez changé pour ', alors laissez-moi effacer mon commentaire, merci, ça marche très bien, +1

1 votes

@S.Mark : &apos; n'appartient pas aux entités HTML 4, voilà pourquoi ! w3.org/TR/html4/sgml/entités.html fishbowl.pastiche.org/2003/07/01/la_curse_des_apos

2 votes

Voir aussi la note de @kender sur la faible sécurité de cette approche.

40voto

Chris Fulstow Points 19762

Si vous utilisez jQuery :

function htmlDecode(value){ 
  return $('<div/>').html(value).text(); 
}

Dans le cas contraire, utiliser L'objet encodeur de Strictly Software qui dispose d'une excellente htmlDecode() fonction.

63 votes

Ne l'utilisez pas (je répète : PAS) pour du contenu généré par l'utilisateur autre que le contenu généré par este l'utilisateur. Si la valeur contient une balise <script>, le contenu de la balise script sera exécuté !

0 votes

Je ne trouve pas de licence pour cela sur le site. Savez-vous de quelle licence il s'agit ?

0 votes

Il y a une licence dans l'en-tête de la source, c'est la GPL.

3voto

nerijus Points 136

La réponse de Chris est belle et élégante, mais elle échoue si la valeur est indéfini . Une simple amélioration le rend solide :

function htmlDecode(value) {
   return (typeof value === 'undefined') ? '' : $('<div/>').html(value).text();
}

3voto

kender Points 18446

Ce n'est pas une réponse directe à votre question, mais ne serait-il pas préférable que votre RPC renvoie une structure (que ce soit XML ou JSON ou autre) avec ces données d'image (urls dans votre exemple) à l'intérieur de cette structure ?

Ensuite, vous pouvez simplement l'analyser dans votre javascript et construire le fichier <img> en utilisant le javascript lui-même.

La structure que vous recevez du CPR pourrait ressembler à ce qui suit :

{"img" : ["myimage.jpg", "myimage2.jpg"]}

Je pense que c'est mieux ainsi, car injecter un code provenant d'une source externe dans votre page ne semble pas très sûr. Imaginez que quelqu'un détourne votre script XML-RPC et y mette quelque chose que vous ne voudriez pas (même du javascript...).

0 votes

L'approche @CMS ci-dessus présente-t-elle cette faille de sécurité ?

1 votes

Je viens d'essayer htmlDecode("&lt;img src='myimage.jpg'&gt;&lt;script&gt;alert('xxxxx');&lt;/scrip‌​t&gt;") et rien ne s'est passé. J'ai obtenu la chaîne html décodée comme prévu.

0voto

Serj Sagan Points 2731

Si vous pouvez placer votre image dans un conteneur, c'est encore plus facile :

HTML :

<div class="container">
    <img src='myimage.jpg'>
</div>

jQuery :

$(".container").html($(".container").text());

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