Ich habe einen Javascript-Code, der mit einem XML-RPC-Backend kommuniziert .. Die XML-RPC gibt Zeichenfolgen des Formulars zurück:
<img src='myimage.jpg'>
Wenn ich jedoch die Zeichenfolgen in HTML stelle, werden sie wörtlich gerendert. Ich sehe kein Bild, ich sehe die Zeichenfolge buchstäblich:
<img src='myimage.jpg'>
Ich vermute, dass der HTML-Code über den XML-RPC-Kanal entkommen ist.
Wie kann ich die Zeichenfolge in Javascript aufheben? Ich habe die Techniken auf dieser Seite erfolglos ausprobiert: http://paulschreiber.com/blog/2008/09/20/javascript-how-to-unescape-html-entities/
Wie kann das Problem auf andere Weise diagnostiziert werden?
Ich verwende die folgende Methode:
function htmlDecode(input){
var e = document.createElement('div');
e.innerHTML = input;
// handle case of empty input
return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}
htmlDecode("<img src='myimage.jpg'>");
// returns "<img src='myimage.jpg'>"
Grundsätzlich erstelle ich ein DOM-Element programmgesteuert, weise den codierten HTML-Code seiner innerHTML zu und rufe den nodeValue aus dem Textknoten ab, der mit der innerHTML-Einfügung erstellt wurde. Da es nur ein Element erstellt, es aber niemals hinzufügt, wird kein Website-HTML-Code geändert.
Es funktioniert cross-browser (einschließlich älterer Browser) und akzeptiert alle HTML Character Entities .
BEARBEITEN: Die alte Version dieses Codes funktionierte auf IE nicht mit leeren Eingaben, wie gezeigt hier auf jsFiddle (Ansicht im IE). Die obige Version funktioniert mit allen Eingängen.
UPDATE: Anscheinend funktioniert das nicht mit großer Zeichenfolge und es wird auch eine Sicherheitsanfälligkeit eingeführt, siehe Kommentare.
Die meisten Antworten, die hier gegeben werden, haben einen großen Nachteil: Wenn die Zeichenfolge, die Sie konvertieren möchten, nicht als vertrauenswürdig eingestuft wird, erhalten Sie am Ende eine Cross-Site Scripting (XSS) -Lücke . Beachten Sie für die Funktion in der akzeptierten Antwort Folgendes:
htmlDecode("<img src='dummy' onerror='alert(/xss/)'>");
Die Zeichenfolge enthält hier ein nicht umschriebenes HTML-Tag, sodass die htmlDecode
-Funktion nicht dekodiert, sondern den in der Zeichenfolge angegebenen JavaScript-Code ausführt.
Dies kann durch die Verwendung von DOMParser vermieden werden, das in allen modernen Browsern unterstützt wird :
function htmlDecode(input)
{
var doc = new DOMParser().parseFromString(input, "text/html");
return doc.documentElement.textContent;
}
// This returns "<img src='myimage.jpg'>"
htmlDecode("<img src='myimage.jpg'>");
// This returns ""
htmlDecode("<img src='dummy' onerror='alert(/xss/)'>");
Diese Funktion führt garantiert keinen JavaScript-Code als Nebeneffekt aus. Alle HTML-Tags werden ignoriert, nur Textinhalt wird zurückgegeben.
Hinweis zur Kompatibilität: Das Analysieren von HTML mit DOMParser
erfordert mindestens Chrome 30, Firefox 12, Opera 17, Internet Explorer 10, Safari 7.1 oder Microsoft Edge. Alle Browser ohne Support sind also weit über ihre EOL hinaus und ab 2017 können nur noch ältere Versionen von Internet Explorer und Safari (in der Regel noch unzählig genug) gesehen werden.
Wenn Sie jQuery verwenden:
function htmlDecode(value){
return $('<div/>').html(value).text();
}
Andernfalls verwenden Sie Strictly Software's Encoder Object , das über eine hervorragende htmlDecode()
-Funktion verfügt.
Der Trick besteht darin, die Stärke des Browsers zu verwenden, um die speziellen HTML-Zeichen zu decodieren, der Browser darf jedoch die Ergebnisse nicht so ausführen, als wäre er HTML. Diese Funktion verwendet einen regulären Ausdruck, um codierte HTML-Zeichen (ein Zeichen) zu identifizieren und zu ersetzen zu einer Zeit.
function unescapeHtml(html) {
var el = document.createElement('div');
return html.replace(/\&[#0-9a-z]+;/gi, function (enc) {
el.innerHTML = enc;
return el.innerText
});
}
Die Antwort von CMS funktioniert einwandfrei, es sei denn, der HTML-Code, den Sie dekomprimieren möchten, ist sehr lang und länger als 65536 Zeichen. In Chrome wird der innere HTML-Code dann in viele untergeordnete Knoten aufgeteilt, von denen jeder höchstens 65536 lang ist, und Sie müssen diese verketten. Diese Funktion funktioniert auch für sehr lange Zeichenfolgen:
function unencodeHtmlContent(escapedHtml) {
var elem = document.createElement('div');
elem.innerHTML = escapedHtml;
var result = '';
// Chrome splits innerHTML into many child nodes, each one at most 65536.
// Whereas FF creates just one single huge child node.
for (var i = 0; i < elem.childNodes.length; ++i) {
result = result + elem.childNodes[i].nodeValue;
}
return result;
}
In dieser Antwort zu innerHTML
max Länge finden Sie weitere Informationen: https://stackoverflow.com/a/27545633/694469
Chris Antwort ist schön und elegant, aber es schlägt fehl, wenn der Wert undefined ist. Nur eine einfache Verbesserung macht es solide:
function htmlDecode(value) {
return (typeof value === 'undefined') ? '' : $('<div/>').html(value).text();
}
Keine direkte Antwort auf Ihre Frage, aber wäre es nicht besser für Ihren RPC, eine Struktur (sei es XML oder JSON oder was auch immer) mit diesen Bilddaten (in Ihrem Beispiel URLs) in dieser Struktur zurückzugeben?
Dann könnten Sie es einfach in Ihrem Javascript analysieren und den <img>
mit Javascript selbst erstellen.
Die Struktur, die Sie von RPC erhalten, könnte folgendermaßen aussehen:
{"img" : ["myimage.jpg", "myimage2.jpg"]}
Ich denke, es ist besser so, da das Einfügen eines Codes aus externen Quellen in Ihre Seite nicht sehr sicher aussieht. Stellen Sie sich vor, wie jemand Ihr XML-RPC-Skript entführt und dort etwas eingefügt hat, was Sie nicht möchten (sogar etwas Javascript ...).
Gern geschehen ... nur ein Bote ... das volle Verdienst geht an ourcodeworld.com, Link unten.
window.htmlentities = {
/**
* Converts a string to its html characters completely.
*
* @param {String} str String with unescaped HTML characters
**/
encode : function(str) {
var buf = [];
for (var i=str.length-1;i>=0;i--) {
buf.unshift(['&#', str[i].charCodeAt(), ';'].join(''));
}
return buf.join('');
},
/**
* Converts an html characterSet into its original character.
*
* @param {String} str htmlSet entities
**/
decode : function(str) {
return str.replace(/&#(\d+);/g, function(match, dec) {
return String.fromCharCode(dec);
});
}
};
Volle Gutschrift: https://ourcodeworld.com/articles/read/188/encode-and-decode-html-entities-using-pure-javascript
Das ist ein besseres:
String::decode = ->
$('<textarea />').html(this).text()
benutzen:
"<img src='myimage.jpg'>".decode();
von: HTML Entity Decode
Alle anderen Antworten hier haben Probleme.
Die document.createElement ('div') -Methoden (einschließlich der Methoden, die jQuery verwenden) führen alle an sie übergebenen Javascript aus (ein Sicherheitsrisiko), und die DOMParser.parseFromString () - Methode trimmt Whitespace. Hier ist eine reine Javascript-Lösung, die kein Problem hat:
function htmlDecode(html) {
var textarea = document.createElement("textarea");
html= html.replace(/\r/g, String.fromCharCode(0xe000)); // Replace "\r" with reserved unicode character.
textarea.innerHTML = html;
var result = textarea.value;
return result.replace(new RegExp(String.fromCharCode(0xe000), 'g'), '\r');
}
TextArea wird speziell verwendet, um die Ausführung von js-Code zu vermeiden. Es passiert diese:
htmlDecode('<& >'); // returns "<& >" with non-breaking space.
htmlDecode(' '); // returns " "
htmlDecode('<img src="dummy" onerror="alert(\'xss\')">'); // Does not execute alert()
htmlDecode('\r\n') // returns "\r\n", doesn't lose the \r like other solutions.
Ich verwende dies in meinem Projekt: Inspiriert von anderen Antworten aber mit einem zusätzlichen sicheren Parameter kann es nützlich sein, wenn Sie mit dekorierten Zeichen umgehen
var decodeEntities=(function(){
var el=document.createElement('div');
return function(str, safeEscape){
if(str && typeof str === 'string'){
str=str.replace(/\</g, '<');
el.innerHTML=str;
if(el.innerText){
str=el.innerText;
el.innerText='';
}
else if(el.textContent){
str=el.textContent;
el.textContent='';
}
if(safeEscape)
str=str.replace(/\</g, '<');
}
return str;
}
})();
Und es ist verwendbar wie:
var label='safe <b> character éntity</b>';
var safehtml='<div title="'+decodeEntities(label)+'">'+decodeEntities(label, true)+'</div>';