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: 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'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 xxx-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 = '高级程序设计';
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("<img src onerror='alert(0)'>"));
});
</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
