Respuestas:
Nota de seguridad: el uso de esta respuesta (preservada en su forma original a continuación) puede introducir una vulnerabilidad XSS en su aplicación. No deberías usar esta respuesta. Lea la respuesta de lucascaro para obtener una explicación de las vulnerabilidades en esta respuesta, y utilice el enfoque de esa respuesta o de la respuesta de Mark Amery .
En realidad, intenta
var decoded = $("<div/>").html(encodedStr).text();
$("<div/>").html('<img src="http://www.google.com/images/logos/ps_logo2.png" onload=alert(1337)>')
. En Firefox o Safari, activa la alerta.
str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/g, "")
o algo similar.
Sin ningún jQuery:
function decodeEntities(encodedString) {
var textArea = document.createElement('textarea');
textArea.innerHTML = encodedString;
return textArea.value;
}
console.log(decodeEntities('1 & 2')); // '1 & 2'
Esto funciona de manera similar a la respuesta aceptada , pero es seguro de usar con la entrada del usuario no confiable.
Como señaló Mike Samuel , hacer esto con una entrada de usuario en <div>
lugar de una <textarea>
sin confianza es una vulnerabilidad XSS, incluso si <div>
nunca se agrega 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)">')
Sin embargo, este ataque no es posible contra a <textarea>
porque no hay elementos HTML que tengan contenido permitido de a <textarea>
. En consecuencia, cualquier etiqueta HTML que todavía esté presente en la cadena 'codificada' será automáticamente codificada por el navegador.
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)">'))
Advertencia : Hacer esto usando jQuery
.html()
y.val()
métodos en lugar de usar.innerHTML
y.value
también es inseguro * para algunas versiones de jQuery, incluso cuando se usa atextarea
. Esto se debe a que las versiones anteriores de jQuery evaluarían deliberada y explícitamente los scripts contenidos en la cadena que se pasa.html()
. Por lo tanto, un código como este muestra una alerta en 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>
* Gracias a Eru Penkman por detectar esta vulnerabilidad.
decodedString = textArea.value;
textArea.remove();
return decodedString;
if ('remove' in Element.prototype) textArea.remove();
$("<div />").html(string).text()
ejecutará cualquier javascript en la cadena provista , lo que sospecho es lo que estaba causando su problema. La respuesta aceptada debe actualizarse a esta.
Como dijo Mike Samuel, no use jQuery.html (). Text () para decodificar entidades html ya que no es seguro.
En su lugar, use un renderizador de plantillas como Moustache.js o decodeEntities del comentario de @ VyvIT.
Underscore.js biblioteca de utilidades de correa viene con escape
y unescape
métodos, pero que no son seguros para la entrada del usuario:
unescape
en los documentos por ahora, por cierto.
_.unescape("'")
da como resultado solo "& # 39;" en lugar de una comilla simple. ¿Hay algo que me falta o el subrayado no se escapa a los códigos de entidad HTML como se muestra en: w3schools.com/tags/ref_entities.asp
escape
y los unescape
métodos ... no son seguros para la entrada del usuario" . ¿Qué quiere decir con esto? A mí me parece una tontería, pero tal vez me estoy perdiendo algo, ¿puedes aclararlo?
_.unescape("<img src=fake onerror=alert('boo!')>")
(en Chrome / FF / IE). Pero no apareció ninguna alerta. Lo probé en la consola y también lo puse en mi archivo JS. Mismo resultado.
Creo que estás confundiendo los métodos de texto y HTML. Mire este ejemplo, si usa el HTML interno de un elemento como texto, obtendrá etiquetas HTML decodificadas (segundo botón). Pero si los usa como HTML, obtendrá la vista con formato HTML (primer botón).
<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>
Primer botón escribe: aquí hay un contenido HTML .
El segundo botón escribe: aquí hay un contenido <B> HTML </B>.
Por cierto, puede ver un complemento que encontré en el complemento jQuery: decodificación y codificación HTML que codifica y decodifica cadenas HTML.
La pregunta está limitada por 'con jQuery', pero podría ayudar a algunos saber que el código jQuery que figura en la mejor respuesta aquí hace lo siguiente debajo ... esto funciona con o sin jQuery:
function decodeEntities(input) {
var y = document.createElement('textarea');
y.innerHTML = input;
return y.value;
}
Puede usar la biblioteca he , disponible en https://github.com/mathiasbynens/he
Ejemplo:
console.log(he.decode("Jörg & Jürgen rocked to & fro "));
// Logs "Jörg & Jürgen rocked to & fro"
Me reté autor de la biblioteca sobre la cuestión de si había alguna razón para utilizar esta biblioteca en el código del lado del cliente a favor del <textarea>
corte previsto en otras respuestas , aquí y en otros lugares. Proporcionó algunas justificaciones posibles:
Si está utilizando el servidor de node.js, el uso de una biblioteca para la codificación / decodificación HTML le brinda una solución única que funciona tanto en el lado del cliente como en el servidor.
Algunos algoritmos de decodificación de entidades de los navegadores tienen errores o les falta soporte para algunas referencias de caracteres con nombre . Por ejemplo, Internet Explorer decodificará y renderizará espacios que no se rompen (
) correctamente, pero los informará como espacios ordinarios en lugar de espacios que no se rompen a través de la innerText
propiedad de un elemento DOM , rompiendo el <textarea>
pirateo (aunque solo de una manera menor). Además, IE 8 y 9 simplemente no admiten ninguna de las nuevas referencias de caracteres con nombre agregadas en HTML 5. El autor de él también presenta una prueba de compatibilidad con referencias de caracteres con nombre en http://mathias.html5.org/tests/html / referencias-caracteres-nombrados / . En IE 8, informa más de mil errores.
Si desea aislarse de los errores del navegador relacionados con la decodificación de entidades y / o poder manejar la gama completa de referencias de caracteres con nombre, no puede salirse con la suya <textarea>
; Necesitarás una biblioteca como él .
Simplemente siente que hacer las cosas de esta manera es menos hacky.
codificar:
$("<textarea/>").html('<a>').html(); // return '<a>'
descodificar:
$("<textarea/>").html('<a>').val() // return '<a>'
Utilizar
myString = myString.replace( /\&/g, '&' );
Es más fácil hacerlo en el lado del servidor porque aparentemente JavaScript no tiene una biblioteca nativa para manejar entidades, ni encontré ninguna cerca de la parte superior de los resultados de búsqueda para los diversos marcos que extienden JavaScript.
Busque "entidades HTML JavaScript", y puede encontrar algunas bibliotecas para ese propósito, pero probablemente todas se construirán en torno a la lógica anterior: reemplazar, entidad por entidad.
Solo tenía que tener un carácter de entidad HTML (⇓) como valor para un botón HTML. El código HTML se ve bien desde el principio en el navegador:
<input type="button" value="Embed & Share ⇓" id="share_button" />
Ahora estaba agregando una palanca que también debería mostrar el personaje. Esta es mi solucion
$("#share_button").toggle(
function(){
$("#share").slideDown();
$(this).attr("value", "Embed & Share " + $("<div>").html("⇑").text());
}
Esto muestra ⇓ nuevamente en el botón. Espero que esto pueda ayudar a alguien.
"Embed & Share \u21d1"
), o mejor aún, solo "Embed & Share ⇑"
si puede servir su script en UTF-8 (o UTF-16, o cualquier otra codificación que admita el carácter ⇑). El uso de un elemento DOM para analizar una entidad HTML solo para hornear un carácter unicode arbitrario en una cadena de JavaScript es un enfoque astuto y creativo que enorgullecería a Rube Goldberg, pero no es una buena práctica; los escapes de Unicode están en el lenguaje específicamente para manejar este caso de uso.
Debe hacer una función personalizada para las entidades html:
function htmlEntities(str) {
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g,'>').replace(/"/g, '"');
}
Supongamos que tienes debajo de String.
Nuestras cabañas de lujo son cálidas, acogedoras y amplias; cómodo
var str = $("p").text(); // get the text from <p> tag
$('p').html(str).text(); // Now,decode html entities in your variable i.e
str y asignar de nuevo a
etiqueta.
Eso es.
Para usuarios de ExtJS, si ya tiene la cadena codificada, por ejemplo, cuando el valor devuelto de una función de biblioteca es el contenido innerHTML, considere esta función ExtJS:
Ext.util.Format.htmlDecode(innerHtmlContent)
Extender una clase de cadena:
String::decode = ->
$('<textarea />').html(this).text()
y usar como método:
"<img src='myimage.jpg'>".decode()
Prueba esto :
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 es una función en la biblioteca Jquery y devolverá una matriz que incluye algunos detalles sobre la cadena dada.
en algunos casos, la cadena es grande, por lo que la función separará el contenido en muchos índices.
y para obtener todos los datos de los índices, debe ir a cualquier índice y luego acceder al índice llamado "wholeText".
Elegí el índice 0 porque funcionará en todos los casos (cadena pequeña o cadena grande).
Todavía hay un problema: la cadena de escape no parece legible cuando se asigna al valor de entrada
var string = _.escape("<img src=fake onerror=alert('boo!')>");
$('input').val(string);
Exapmle: https://jsfiddle.net/kjpdwmqa/3/
escape
método de Underscore.js. Tampoco hay explicación de cómo su ejemplo de código debería resolver el problema de OP.
Alternativamente, también hay una biblioteca para ello.
aquí, https://cdnjs.com/libraries/he
npm install he //using node.js
<script src="js/he.js"></script> //or from your javascript directory
El uso es el siguiente ...
//to encode text
he.encode('© Ande & Nonso® Company LImited 2018');
//to decode the
he.decode('© Ande & Nonso® Company Limited 2018');
salud.
Para decodificar entidades HTML con jQuery, solo use esta función:
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;
}
Cómo utilizar:
Javascript:
var txtEncoded = "á é í ó ú";
$('#some-id').val(html_entity_decode(txtEncoded));
HTML:
<input id="some-id" type="text" />
La forma más fácil es establecer un selector de clase para sus elementos y luego usar el siguiente código:
$(function(){
$('.classSelector').each(function(a, b){
$(b).html($(b).text());
});
});
¡Nada más necesario!
Tuve este problema y encontré esta solución clara y funciona bien.