javascript - Hva er den riktige måten å dekode en streng som har spesielle HTML-enheter i seg?


La oss si at jeg får tilbake noen JSON fra en tjenesteforespørsel som ser slik ut:

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

Jeg er ikke sikker på hvorfor den apostraphe kodes slik ('); alt jeg vet er at jeg vil dekode det.

Her er en tilnærming ved bruk av jQuery som dukket opp i hodet mitt:

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

Det virker (veldig) løsrevet, da. Hva er en bedre måte? Finnes det en «riktig» måte?

Svar #1

Dette er min favorittmåte å dekode HTML-tegn på. Fordelen med å bruke denne koden er at tagger også bevares.

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

Eksempel: http://jsfiddle.net/k65s3/

Inndata :

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

Utdata :

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

Svar #2

Ikke bruk DOM for å gjøre dette hvis du bryr deg om kompatibilitet med eldre nettlesere. Å bruke DOM for å dekode HTML-enheter (som foreslått i det nåværende aksepterte svaret) fører til forskjeller i resultater på tvers av nettlesere på ikke-moderne nettlesere.

For en robust og deterministisk løsning som dekoder tegnreferanser i henhold til algoritmen i HTML-standarden, bruk he-biblioteket. Fra dens README:

han (for "HTML-entiteter") er en robust HTML-entitetskoder/dekoder skrevet i JavaScript. Den støtter alle standardiserte navngitte tegnreferanser i henhold til HTML, håndterer tvetydige tegn og andre kanttilfeller akkurat som en nettleser, har en omfattende testpakke, og — i motsetning til mange andre JavaScript-løsninger — håndterer den astrale Unicode-symboler uten problemer. En nettbasert demo er tilgjengelig.

Slik vil du bruke det:

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

Ansvarsfraskrivelse: Jeg er forfatteren av he-biblioteket.

Se dette Stack Overflow-svaret for mer informasjon.

Svar #3

Hvis du ikke vil bruke html/dom, kan du bruke regex. Jeg har ikke testet dette; men noe i retning av:

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

[Rediger]

Merk: dette vil bare fungere for numeriske HTML-enheter, og ikke ting som &oring;.

[Rediger 2]

Fikset funksjonen (noen skrivefeil), test her: http://jsfiddle.net/Be2Bd/1/

Svar #4

Det finnes en JS-funksjon for å håndtere &#xxxx-stilte enheter:
funksjon på 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 = '高级程序设计';

let element = document.getElementById("testFunct");
element.innerHTML = (decodeHtmlEntity(entity));

console.log(decodeHtmlEntity(entity) === str);
console.log(encodeHtmlEntity(str) === entity);
// output:
// true
// true
<div><span id="testFunct"></span></div>

Svar #5

jQuery vil kode og dekode for deg.

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>

Svar #6

_.unescape gjør det du leter etter

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

Relaterte artikler