286 votes

Quelle est la bonne façon de décoder une chaîne contenant des entités HTML spéciales ?

Disons que je récupère du JSON à partir d'une demande de service qui ressemble à ceci :

 {
    "message": "We're unable to complete your request at this time."
}

Je ne sais pas pourquoi cette apostraphe est codée comme ça ( ' ); tout ce que je sais, c'est que je veux le décoder.

Voici une approche utilisant jQuery qui m'est venue à l'esprit :

 function decodeHtml(html) {
    return $('<div>').html(html).text();
}

Cela semble (très) hacky, cependant. Quelle est la meilleure façon ? Existe-t-il une "bonne" méthode ?

569voto

Rob W Points 125904

C'est ma façon préférée de décoder les caractères HTML. L'avantage d'utiliser ce code est que les balises sont également conservées.

 function decodeHtml(html) {
    var txt = document.createElement("textarea");
    txt.innerHTML = html;
    return txt.value;
}

Exemple : http://jsfiddle.net/k65s3/

Contribution:

 Entity:&nbsp;Bad attempt at XSS:<script>alert('new\nline?')</script><br>

Production:

 Entity: Bad attempt at XSS:<script>alert('new\nline?')</script><br>

46voto

Alxandr Points 5413

Si vous ne voulez pas utiliser html/dom, vous pouvez utiliser regex. Je n'ai pas testé cela ; mais quelque chose du genre :

 function parseHtmlEntities(str) {
    return str.replace(/&#([0-9]{1,3});/gi, function(match, numStr) {
        var num = parseInt(numStr, 10); // read num as normal number
        return String.fromCharCode(num);
    });
}

[Éditer]

Remarque : cela ne fonctionnerait que pour les entités html numériques, et non pour des choses comme &oring;.

[Modifier 2]

Correction de la fonction (quelques fautes de frappe), testez ici : http://jsfiddle.net/Be2Bd/1/

38voto

user2733283 Points 11

jQuery encodera et décodera pour vous.

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

function htmlEncode(value) {
  return $('<textarea/>').text(value).html();
}
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
   $("#encoded")
  .text(htmlEncode("<img src onerror='alert(0)'>"));
   $("#decoded")
  .text(htmlDecode("&lt;img src onerror='alert(0)'&gt;"));
});
</script>

<span>htmlEncode() result:</span><br/>
<div id="encoded"></div>
<br/>
<span>htmlDecode() result:</span><br/>
<div id="decoded"></div>

38voto

hypers Points 367

Il existe une fonction JS pour gérer les entités de style &#xxxx : fonction sur GitHub

 // encode(decode) html text into html entity
var decodeHtmlEntity = function(str) {
  return str.replace(/&#(\d+);/g, function(match, dec) {
    return String.fromCharCode(dec);
  });
};

var encodeHtmlEntity = function(str) {
  var buf = [];
  for (var i=str.length-1;i>=0;i--) {
    buf.unshift(['&#', str[i].charCodeAt(), ';'].join(''));
  }
  return buf.join('');
};

var entity = '&#39640;&#32423;&#31243;&#24207;&#35774;&#35745;';
var str = '';
console.log(decodeHtmlEntity(entity) === str);
console.log(encodeHtmlEntity(str) === entity);
// output:
// true
// true

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