Wie verwende ich jQuery, um HTML-Entitäten in einer Zeichenfolge zu dekodieren?
Wie verwende ich jQuery, um HTML-Entitäten in einer Zeichenfolge zu dekodieren?
Antworten:
Sicherheitshinweis: Die Verwendung dieser Antwort (in der unten angegebenen Originalform erhalten) kann zu einer XSS-Sicherheitsanfälligkeit in Ihrer Anwendung führen. Sie sollten diese Antwort nicht verwenden. Lesen Sie die Antwort von Lucascaro, um eine Erklärung der Schwachstellen in dieser Antwort zu erhalten, und verwenden Sie stattdessen entweder den Ansatz dieser Antwort oder die Antwort von Mark Amery .
Versuchen Sie es tatsächlich
var decoded = $("<div/>").html(encodedStr).text();
$("<div/>").html('<img src="http://www.google.com/images/logos/ps_logo2.png" onload=alert(1337)>')
. In Firefox oder Safari wird die Warnung ausgelöst.
str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/g, "")
oder etwas ähnliches.
Ohne jQuery:
function decodeEntities(encodedString) {
var textArea = document.createElement('textarea');
textArea.innerHTML = encodedString;
return textArea.value;
}
console.log(decodeEntities('1 & 2')); // '1 & 2'
Dies funktioniert ähnlich wie die akzeptierte Antwort , kann jedoch sicher mit nicht vertrauenswürdigen Benutzereingaben verwendet werden.
Wie von Mike Samuel bemerkt , ist dies eine XSS-Sicherheitsanfälligkeit, wenn dies nicht mit einer nicht vertrauenswürdigen Benutzereingabe, <div>
sondern mit einer <textarea>
nicht vertrauenswürdigen Benutzereingabe erfolgt, selbst wenn die <div>
niemals zum DOM hinzugefügt wird:
function decodeEntities(encodedString) {
var div = document.createElement('div');
div.innerHTML = encodedString;
return div.textContent;
}
// Shows an alert
decodeEntities('<img src="nonexistent_image" onerror="alert(1337)">')
Dieser Angriff ist jedoch gegen a nicht möglich, <textarea>
da keine HTML-Elemente vorhanden sind, deren Inhalt zulässig ist <textarea>
. Folglich werden alle HTML-Tags, die noch in der 'codierten' Zeichenfolge vorhanden sind, vom Browser automatisch entitätscodiert.
function decodeEntities(encodedString) {
var textArea = document.createElement('textarea');
textArea.innerHTML = encodedString;
return textArea.value;
}
// Safe, and returns the correct answer
console.log(decodeEntities('<img src="nonexistent_image" onerror="alert(1337)">'))
Achtung : Dadurch jQuery verwenden
.html()
und.val()
anstelle der Verwendung von Methoden.innerHTML
und.value
ist auch unsicher * für einige Versionen von jQuery, selbst wenn eine Verwendungtextarea
. Dies liegt daran, dass ältere Versionen von jQuery Skripte, die in der übergebenen Zeichenfolge enthalten sind, absichtlich und explizit auswerten.html()
. Daher zeigt Code wie dieser eine Warnung in jQuery 1.8:
//<!-- CDATA
// Shows alert
$("<textarea>")
.html("<script>alert(1337);</script>")
.text();
//-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
* Vielen Dank an Eru Penkman , der diese Sicherheitsanfälligkeit entdeckt hat.
decodedString = textArea.value;
textArea.remove();
return decodedString;
if ('remove' in Element.prototype) textArea.remove();
$("<div />").html(string).text()
führt jedes Javascript in der angegebenen Zeichenfolge aus , was vermutlich Ihr Problem verursacht hat. Die akzeptierte Antwort sollte auf diese aktualisiert werden.
Wie Mike Samuel sagte, verwenden Sie jQuery.html (). Text () nicht, um HTML-Entitäten zu dekodieren, da dies unsicher ist.
Verwenden Sie stattdessen einen Vorlagenrenderer wie Moustache.js oder decodeEntities aus dem Kommentar von @ VyvIT.
Die Underscore.js Utility-Belt-Bibliothek enthält escape
und unescape
Methoden, die jedoch für Benutzereingaben nicht sicher sind:
unescape
sind übrigens inzwischen in den Dokumenten enthalten.
_.unescape("'")
ergibt nur "& # 39;" anstelle eines einfachen Anführungszeichens. Fehlt
escape
und unescape
Methoden ... für Benutzereingaben nicht sicher sind" . Was meinst du damit? Es klingt für mich nach Unsinn, aber vielleicht fehlt mir etwas - können Sie das klarstellen?
_.unescape("<img src=fake onerror=alert('boo!')>")
(in Chrome / FF / IE). Aber es zeigte sich keine Warnung. Versuchte es in der Konsole und legte es auch in meine JS-Datei. Gleiches Ergebnis.
Ich denke, Sie verwechseln die Text- und HTML-Methoden. In diesem Beispiel erhalten Sie dekodierte HTML-Tags (zweite Schaltfläche), wenn Sie den inneren HTML-Code eines Elements als Text verwenden. Wenn Sie sie jedoch als HTML verwenden, erhalten Sie die HTML-formatierte Ansicht (erste Schaltfläche).
<div id="myDiv">
here is a <b>HTML</b> content.
</div>
<br />
<input value="Write as HTML" type="button" onclick="javascript:$('#resultDiv').html($('#myDiv').html());" />
<input value="Write as Text" type="button" onclick="javascript:$('#resultDiv').text($('#myDiv').html());" />
<br /><br />
<div id="resultDiv">
Results here !
</div>
Erste Schaltfläche schreibt: Hier ist ein HTML- Inhalt.
Zweite Schaltfläche schreibt: Hier ist ein <B> HTML </ B> -Inhalt.
Übrigens können Sie ein Plug-In sehen, das ich im jQuery-Plugin gefunden habe - HTML-Dekodierung und -Codierung , die HTML-Zeichenfolgen codiert und decodiert.
Die Frage ist durch 'mit jQuery' begrenzt, aber es kann einigen helfen zu wissen, dass der in der besten Antwort hier angegebene jQuery-Code Folgendes bewirkt ... dies funktioniert mit oder ohne jQuery:
function decodeEntities(input) {
var y = document.createElement('textarea');
y.innerHTML = input;
return y.value;
}
Sie können die Verwendung er Bibliothek von https://github.com/mathiasbynens/he
Beispiel:
console.log(he.decode("Jörg & Jürgen rocked to & fro "));
// Logs "Jörg & Jürgen rocked to & fro"
Ich habe den Autor der Bibliothek in der Frage herausgefordert, ob es einen Grund gibt, diese Bibliothek im clientseitigen Code zu verwenden, und zwar zugunsten des <textarea>
Hacks, der in anderen Antworten hier und anderswo angegeben ist. Er lieferte einige mögliche Begründungen:
Wenn Sie die serverseitige Datei node.js verwenden, erhalten Sie durch die Verwendung einer Bibliothek für die HTML-Codierung / -Decodierung eine einzige Lösung, die sowohl clientseitig als auch serverseitig funktioniert.
Die Entitätsdecodierungsalgorithmen einiger Browser weisen Fehler auf oder es fehlt die Unterstützung für einige benannte Zeichenreferenzen . Beispielsweise dekodiert und rendert Internet Explorer nicht unterbrechende Leerzeichen (
) korrekt, meldet sie jedoch als normale Leerzeichen anstelle von nicht unterbrechenden Leerzeichen über die innerText
Eigenschaft eines DOM-Elements und unterbricht den <textarea>
Hack (wenn auch nur in geringem Umfang). Zusätzlich IE 8 und 9 einfach nicht unterstützen , eine der neuen benannten Zeichenreferenzen hinzugefügt in HTML 5. Der Autor er auch einen Test der benannten Zeichenreferenz Unterstützung findet bei http://mathias.html5.org/tests/html / Named-Character-Referenzen / . In IE 8 werden über tausend Fehler gemeldet.
Wenn Sie vor Browserfehlern im Zusammenhang mit der Entschlüsselung von Entitäten isoliert werden möchten und / oder in der Lage sein möchten, die gesamte Bandbreite der benannten Zeichenreferenzen zu verarbeiten, können Sie mit dem <textarea>
Hack nicht durchkommen . Du brauchst eine Bibliothek wie er .
Er hat einfach das verdammte Gefühl, dass es weniger hackig ist, Dinge auf diese Weise zu tun.
kodieren:
$("<textarea/>").html('<a>').html(); // return '<a>'
dekodieren:
$("<textarea/>").html('<a>').val() // return '<a>'
Verwenden
myString = myString.replace( /\&/g, '&' );
Es ist am einfachsten, dies auf der Serverseite zu tun, da JavaScript anscheinend keine native Bibliothek für die Verarbeitung von Entitäten hat und ich auch keine in den Suchergebnissen für die verschiedenen Frameworks gefunden habe, die JavaScript erweitern.
Suchen Sie nach "JavaScript-HTML-Entitäten", und Sie finden möglicherweise einige Bibliotheken für diesen Zweck, aber sie werden wahrscheinlich alle auf der obigen Logik basieren - ersetzen Sie Entität durch Entität.
Ich musste nur einen HTML-Entity-Charater (⇓) als Wert für eine HTML-Schaltfläche haben. Der HTML-Code sieht im Browser von Anfang an gut aus:
<input type="button" value="Embed & Share ⇓" id="share_button" />
Jetzt habe ich einen Schalter hinzugefügt, der auch den Charakter anzeigen soll. Das ist meine Lösung
$("#share_button").toggle(
function(){
$("#share").slideDown();
$(this).attr("value", "Embed & Share " + $("<div>").html("⇑").text());
}
Dies zeigt ⇓ erneut in der Schaltfläche an. Ich hoffe das könnte jemandem helfen.
"Embed & Share \u21d1"
) zu verwenden, oder noch besser, "Embed & Share ⇑"
wenn Sie Ihr Skript in UTF-8 (oder UTF-16 oder einer anderen Codierung, die das Zeichen ⇑ unterstützt) bereitstellen können. Die Verwendung eines DOM-Elements zum Parsen einer HTML-Entität, nur um ein beliebiges Unicode-Zeichen in eine JavaScript-Zeichenfolge zu backen, ist ein gerissener und kreativer Ansatz, der Rube Goldberg stolz machen würde, aber keine gute Praxis ist. Unicode-Escapezeichen sind in der Sprache speziell für diesen Anwendungsfall.
Sie müssen benutzerdefinierte Funktionen für HTML-Entitäten erstellen:
function htmlEntities(str) {
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g,'>').replace(/"/g, '"');
}
Angenommen, Sie haben unten String.
Unsere Deluxe-Kabinen sind warm, gemütlich & amp; komfortabel
var str = $("p").text(); // get the text from <p> tag
$('p').html(str).text(); // Now,decode html entities in your variable i.e
str und zurück zuweisen
Etikett.
das ist es.
Wenn Sie für ExtJS-Benutzer bereits über die codierte Zeichenfolge verfügen, z. B. wenn der zurückgegebene Wert einer Bibliotheksfunktion der innerHTML-Inhalt ist, sollten Sie diese ExtJS-Funktion berücksichtigen:
Ext.util.Format.htmlDecode(innerHtmlContent)
Erweitern Sie eine String-Klasse:
String::decode = ->
$('<textarea />').html(this).text()
und als Methode verwenden:
"<img src='myimage.jpg'>".decode()
Versuche dies :
var htmlEntities = "<script>alert('hello');</script>";
var htmlDecode =$.parseHTML(htmlEntities)[0]['wholeText'];
console.log(htmlDecode);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
parseHTML ist eine Funktion in der Jquery-Bibliothek und gibt ein Array zurück, das einige Details zum angegebenen String enthält.
In einigen Fällen ist der String groß, sodass die Funktion den Inhalt in viele Indizes aufteilt.
und um alle Indexdaten zu erhalten, sollten Sie zu einem beliebigen Index gehen und dann auf den Index mit dem Namen "WholeText" zugreifen.
Ich habe Index 0 gewählt, weil er in allen Fällen funktioniert (kleiner oder großer String).
Hier ist noch ein Problem: Escaped String sieht nicht lesbar aus, wenn es dem Eingabewert zugewiesen wird
var string = _.escape("<img src=fake onerror=alert('boo!')>");
$('input').val(string);
Beispiel: https://jsfiddle.net/kjpdwmqa/3/
escape
Methode Underscore.js. Es gibt auch keine Erklärung, wie Ihr Codebeispiel das Problem von OP lösen sollte.
Alternativ gibt es auch eine Bibliothek dafür ..
hier https://cdnjs.com/libraries/he
npm install he //using node.js
<script src="js/he.js"></script> //or from your javascript directory
Die Verwendung ist wie folgt ...
//to encode text
he.encode('© Ande & Nonso® Company LImited 2018');
//to decode the
he.decode('© Ande & Nonso® Company Limited 2018');
Prost.
Verwenden Sie zum Dekodieren von HTML-Entitäten mit jQuery einfach die folgende Funktion:
function html_entity_decode(txt){
var randomID = Math.floor((Math.random()*100000)+1);
$('body').append('<div id="random'+randomID+'"></div>');
$('#random'+randomID).html(txt);
var entity_decoded = $('#random'+randomID).html();
$('#random'+randomID).remove();
return entity_decoded;
}
Wie benutzt man:
Javascript:
var txtEncoded = "á é í ó ú";
$('#some-id').val(html_entity_decode(txtEncoded));
HTML:
<input id="some-id" type="text" />
Am einfachsten ist es, eine Klassenauswahl für Ihre Elemente festzulegen und dann den folgenden Code zu verwenden:
$(function(){
$('.classSelector').each(function(a, b){
$(b).html($(b).text());
});
});
Nichts mehr nötig!
Ich hatte dieses Problem und fand diese klare Lösung und es funktioniert gut.