Risposte:
Nota di sicurezza: l' utilizzo di questa risposta (conservata nella sua forma originale di seguito) può introdurre una vulnerabilità XSS nella tua applicazione. Non dovresti usare questa risposta. Leggi la risposta di Lucascaro per una spiegazione delle vulnerabilità in questa risposta e usa invece l'approccio di quella risposta o la risposta di Mark Amery .
In realtà, prova
var decoded = $("<div/>").html(encodedStr).text();
$("<div/>").html('<img src="http://www.google.com/images/logos/ps_logo2.png" onload=alert(1337)>')
. In Firefox o Safari attiva l'avviso.
str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/g, "")
o qualcosa di simile.
Senza jQuery:
function decodeEntities(encodedString) {
var textArea = document.createElement('textarea');
textArea.innerHTML = encodedString;
return textArea.value;
}
console.log(decodeEntities('1 & 2')); // '1 & 2'
Funziona in modo simile alla risposta accettata , ma è sicuro da usare con input dell'utente non attendibile.
Come notato da Mike Samuel , farlo con un input dell'utente <div>
invece di uno <textarea>
non attendibile è una vulnerabilità XSS, anche se <div>
non viene mai aggiunto al DOM:
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)">')
Tuttavia, questo attacco non è possibile contro a <textarea>
perché non ci sono elementi HTML a cui è consentito il contenuto di a <textarea>
. Di conseguenza, tutti i tag HTML ancora presenti nella stringa 'codificata' verranno automaticamente codificati dall'entità dal browser.
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)">'))
Avvertenza : farlo usando jQuery
.html()
e.val()
metodi invece di usare.innerHTML
ed.value
è anche insicuro * per alcune versioni di jQuery, anche quando si usa atextarea
. Questo perché le versioni precedenti di jQuery valutano deliberatamente ed esplicitamente gli script contenuti nella stringa passata a.html()
. Quindi codice come questo mostra un avviso 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>
* Grazie a Eru Penkman per aver colto questa vulnerabilità.
decodedString = textArea.value;
textArea.remove();
return decodedString;
if ('remove' in Element.prototype) textArea.remove();
$("<div />").html(string).text()
eseguirà qualsiasi javascript nella stringa fornita , che sospetto sia la causa del tuo problema. La risposta accettata dovrebbe essere aggiornata a questa.
Come ha detto Mike Samuel, non usare jQuery.html (). Text () per decodificare entità html poiché non è sicuro.
Utilizza invece un renderer di modelli come Moustache.js o decodeEntities dal commento di @ VyvIT.
La libreria di cintura di utilità Underscore.js includeescape
e unescape
metodi, ma non sono sicuri per l'input dell'utente:
unescape
Ormai erano inclusi nei documenti, a proposito.
_.unescape("'")
risulta solo "& # 39;" invece di una virgoletta singola. C'è qualcosa che mi manca o il carattere di sottolineatura non sfugge ai codici entità HTML come mostrato su: w3schools.com/tags/ref_entities.asp
escape
e i unescape
metodi ... di Underscore non sono sicuri per l'input dell'utente" . Cosa intendi con questo? Mi sembra assurdo, ma forse mi manca qualcosa - puoi chiarire?
_.unescape("<img src=fake onerror=alert('boo!')>")
(in Chrome / FF / IE). Ma non ha mostrato alcun avviso. L'ho provato in console e anche nel mio file JS. Stesso risultato
Penso che tu stia confondendo i metodi di testo e HTML. Guarda questo esempio, se usi l'HTML interno di un elemento come testo, otterrai tag HTML decodificati (secondo pulsante). Ma se li usi come HTML, otterrai la visualizzazione in formato HTML (primo pulsante).
<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>
Il primo pulsante scrive: ecco un contenuto HTML .
Il secondo pulsante scrive: ecco un contenuto <B> HTML </B>.
A proposito, puoi vedere un plug-in che ho trovato nel plug-in jQuery: decodifica e codifica HTML che codifica e decodifica stringhe HTML.
La domanda è limitata da 'with jQuery' ma potrebbe aiutare alcuni a sapere che il codice jQuery fornito nella migliore risposta qui fa quanto segue sotto ... funziona con o senza jQuery:
function decodeEntities(input) {
var y = document.createElement('textarea');
y.innerHTML = input;
return y.value;
}
È possibile utilizzare la libreria he , disponibile da https://github.com/mathiasbynens/he
Esempio:
console.log(he.decode("Jörg & Jürgen rocked to & fro "));
// Logs "Jörg & Jürgen rocked to & fro"
Ho sfidato l'autore della biblioteca alla domanda se ci fosse qualche motivo per usare questa libreria nel codice del client a favore <textarea>
dell'hack fornito in altre risposte qui e altrove. Ha fornito alcune possibili giustificazioni:
Se si utilizza il server node.js sul lato, l'utilizzo di una libreria per la codifica / decodifica HTML offre un'unica soluzione che funziona sia sul lato client che sul lato server.
Alcuni algoritmi di decodifica delle entità del browser presentano bug o mancano il supporto per alcuni riferimenti ai caratteri con nome . Ad esempio, Internet Explorer decodificherà e renderizzerà
correttamente gli spazi non interrompibili ( ) ma li riporterà come spazi ordinari anziché non interrompibili tramite la innerText
proprietà di un elemento DOM , interrompendo l' <textarea>
hack (anche se solo in modo minore). Inoltre, IE 8 e 9 semplicemente non supportano nessuno dei nuovi riferimenti ai caratteri nominativi aggiunti in HTML 5. L'autore di lui ospita anche un test di supporto dei riferimenti ai caratteri denominati su http://mathias.html5.org/tests/html / nominati-caratteri-riferimenti / . In IE 8, riporta oltre mille errori.
Se vuoi essere isolato dai bug del browser relativi alla decodifica delle entità e / o essere in grado di gestire l'intera gamma di riferimenti ai personaggi con nome, non puoi cavartela con l' <textarea>
hacking; avrai bisogno di una biblioteca come lui .
Dannatamente ha la sensazione che fare le cose in questo modo sia meno confuso.
codificare:
$("<textarea/>").html('<a>').html(); // return '<a>'
decodificare:
$("<textarea/>").html('<a>').val() // return '<a>'
Uso
myString = myString.replace( /\&/g, '&' );
È più semplice farlo sul lato server perché apparentemente JavaScript non ha una libreria nativa per la gestione delle entità, né ho trovato alcun risultato nella parte superiore dei risultati di ricerca per i vari framework che estendono JavaScript.
Cerca "Entità HTML JavaScript" e potresti trovare alcune librerie solo per quello scopo, ma probabilmente saranno tutte costruite attorno alla logica sopra - sostituire, entità per entità.
Dovevo solo avere un charater di entità HTML (⇓) come valore per un pulsante HTML. Il codice HTML sembra buono fin dall'inizio nel browser:
<input type="button" value="Embed & Share ⇓" id="share_button" />
Ora stavo aggiungendo un interruttore che dovrebbe anche visualizzare il carattere. Questa è la mia soluzione
$("#share_button").toggle(
function(){
$("#share").slideDown();
$(this).attr("value", "Embed & Share " + $("<div>").html("⇑").text());
}
Questo visualizza di nuovo ⇓ nel pulsante. Spero che questo possa aiutare qualcuno.
"Embed & Share \u21d1"
), o meglio ancora solo "Embed & Share ⇑"
se sei in grado di servire il tuo script in UTF-8 (o UTF-16, o qualsiasi altra codifica che supporti il carattere ⇑). Usare un elemento DOM per analizzare un'entità HTML solo per creare un carattere unicode arbitrario in una stringa JavaScript è un approccio astuto e creativo che renderebbe orgoglioso Rube Goldberg, ma non è una buona pratica; gli escape unicode sono nella lingua specifica per gestire questo caso d'uso.
Devi rendere la funzione personalizzata per le entità html:
function htmlEntities(str) {
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g,'>').replace(/"/g, '"');
}
Supponiamo di avere sotto String.
Le nostre cabine Deluxe sono calde, accoglienti e amp; confortevole
var str = $("p").text(); // get the text from <p> tag
$('p').html(str).text(); // Now,decode html entities in your variable i.e
str e assegnare di nuovo a
etichetta.
questo è tutto.
Per gli utenti ExtJS, se si dispone già della stringa codificata, ad esempio quando il valore restituito di una funzione di libreria è il contenuto innerHTML, considerare questa funzione ExtJS:
Ext.util.Format.htmlDecode(innerHtmlContent)
Estendi una classe String:
String::decode = ->
$('<textarea />').html(this).text()
e utilizzare come metodo:
"<img src='myimage.jpg'>".decode()
Prova questo :
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 è una funzione nella libreria Jquery e restituirà un array che include alcuni dettagli sulla stringa specificata.
in alcuni casi la stringa è grande, quindi la funzione separerà il contenuto da molti indici.
e per ottenere tutti i dati degli indici dovresti andare su qualsiasi indice, quindi accedere all'indice chiamato "wholeText".
Ho scelto l'indice 0 perché funzionerà in tutti i casi (stringa piccola o stringa grande).
Qui c'è ancora un problema: la stringa con escape non sembra leggibile quando assegnata al valore di input
var string = _.escape("<img src=fake onerror=alert('boo!')>");
$('input').val(string);
Exapmle: https://jsfiddle.net/kjpdwmqa/3/
escape
metodo di Underscore.js. Inoltre non ci sono spiegazioni su come l'esempio di codice dovrebbe risolvere il problema di OP.
In alternativa, c'è anche una libreria per questo ...
qui, https://cdnjs.com/libraries/he
npm install he //using node.js
<script src="js/he.js"></script> //or from your javascript directory
L'utilizzo è il seguente ...
//to encode text
he.encode('© Ande & Nonso® Company LImited 2018');
//to decode the
he.decode('© Ande & Nonso® Company Limited 2018');
Saluti.
Per decodificare le entità HTML con jQuery, basta usare questa funzione:
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;
}
Come usare:
Javascript:
var txtEncoded = "á é í ó ú";
$('#some-id').val(html_entity_decode(txtEncoded));
HTML:
<input id="some-id" type="text" />
Il modo più semplice è impostare un selettore di classe sui tuoi elementi e quindi utilizzare il seguente codice:
$(function(){
$('.classSelector').each(function(a, b){
$(b).html($(b).text());
});
});
Non serve più nulla!
Ho avuto questo problema e ho trovato questa soluzione chiara e funziona benissimo.