it-swarm.it

Qual è il modo giusto per decodificare una stringa che contiene entità HTML speciali?

Diciamo che ho ricevuto un po 'di JSON da una richiesta di servizio che assomiglia a questo:

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

Non sono sicuro perché che apostraphe sia codificato in quel modo ('); tutto quello che so è che voglio decodificarlo.

Ecco un approccio usando jQuery che mi è venuto in mente:

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

Ciò sembra (molto) hacky, però. Qual è un modo migliore? Esiste un modo "giusto"?

167
Dan Tao

Questo è il mio modo preferito di decifrare i caratteri HTML. Il vantaggio dell'utilizzo di questo codice è che anche i tag sono preservati.

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

Esempio: http://jsfiddle.net/k65s3/

Ingresso:

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

Produzione:

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

Non usare il DOM per fare ciò. Usare il DOM per decodificare le entità HTML (come suggerito nella risposta attualmente accettata) porta a differenze nei risultati del cross-browser .

Per una soluzione robusta e deterministica che decodifica i riferimenti dei caratteri in base all'algoritmo nello standard HTML, usa la he biblioteca . Dal suo README:

he (per "entità HTML") è un codificatore/decodificatore di entità HTML valido scritto in JavaScript. Supporta tutti i riferimenti di carattere con nome standardizzati come per HTML , gestisce ambigui e commerciali e altri casi Edge proprio come farebbe un browser , ha una vasta suite di test e - contrariamente a molte altre soluzioni JavaScript - he gestisce i simboli astrali Unicode bene. È disponibile una demo online.

Ecco come lo useresti:

he.decode("We&#39;re unable to complete your request at this time.");
→ "We're unable to complete your request at this time."

Disclaimer: Sono l'autore della he biblioteca.

Vedi questa risposta Overflow dello stack per ulteriori informazioni.

75
Mathias Bynens

Se non si desidera utilizzare html/dom, è possibile utilizzare regex. Non ho provato questo; ma qualcosa sulla falsariga di:

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);
    });
}

[Modificare]

Nota: questo funzionerebbe solo con entità html numeriche e non roba come & oring ;.

[Modifica 2]

Risolto il problema (alcuni errori di battitura), prova qui: http://jsfiddle.net/Be2Bd/1/

29
Alxandr

jQuery codificherà e decodificherà per te.

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>
25
Jason Williams

C'è una funzione JS da gestire & # xxxx entità con stile:
funzione su 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
19
hypers

_.unescape fa quello che stai cercando

https://lodash.com/docs/#unescape

7
tldr

Questa è una buona risposta. Puoi usare questo con angolare come questo:

 moduleDefinitions.filter('sanitize', ['$sce', function($sce) {
    return function(htmlCode) {
        var txt = document.createElement("textarea");
        txt.innerHTML = htmlCode;
        return $sce.trustAsHtml(txt.value);
    }
}]);
0
kodmanyagha