Tengo un código Javascript que se comunica con un back-end XML-RPC. El XML-RPC devuelve cadenas de la forma:
<img src='myimage.jpg'>
Sin embargo, cuando uso el Javascript para insertar las cadenas en HTML, se procesan literalmente. No veo una imagen, literalmente veo la cadena:
<img src='myimage.jpg'>
Supongo que el HTML se está escapando a través del canal XML-RPC.
¿Cómo puedo eliminar la cadena en Javascript? Probé las técnicas en esta página, sin éxito: http://paulschreiber.com/blog/2008/09/20/javascript-how-to-unescape-html-entities/
¿Cuáles son otras formas de diagnosticar el problema?
javascript
html
escaping
xml-rpc
Joseph Turian
fuente
fuente
Respuestas:
EDITAR: debe usar la API DOMParser como sugiere Wladimir , edité mi respuesta anterior ya que la función publicada introdujo una vulnerabilidad de seguridad.
El siguiente fragmento es el código de la respuesta anterior con una pequeña modificación: el uso de en
textarea
lugar de adiv
reduce la vulnerabilidad de XSS, pero sigue siendo problemático en IE9 y Firefox.Básicamente, creo un elemento DOM mediante programación, asigno el HTML codificado a su innerHTML y recupero el nodeValue del nodo de texto creado en la inserción innerHTML. Como solo crea un elemento pero nunca lo agrega, no se modifica el HTML del sitio.
Funcionará entre navegadores (incluidos los navegadores más antiguos) y aceptará todas las entidades de caracteres HTML .
EDITAR: La versión anterior de este código no funcionaba en IE con entradas en blanco, como se evidencia aquí en jsFiddle (ver en IE). La versión anterior funciona con todas las entradas.
ACTUALIZACIÓN: parece que esto no funciona con una cadena grande, y también presenta una vulnerabilidad de seguridad , vea los comentarios.
fuente
'
no pertenece a las entidades HTML 4, ¡por eso! w3.org/TR/html4/sgml/entities.html fishbowl.pastiche.org/2003/07/01/the_curse_of_aposLa mayoría de las respuestas dadas aquí tienen una gran desventaja: si la cadena que está tratando de convertir no es confiable, terminará con una vulnerabilidad de Cross-Site Scripting (XSS) . Para la función en la respuesta aceptada , considere lo siguiente:
La cadena aquí contiene una etiqueta HTML sin escape, por lo que en lugar de decodificar nada, la
htmlDecode
función realmente ejecutará el código JavaScript especificado dentro de la cadena.Esto se puede evitar utilizando DOMParser, que es compatible con todos los navegadores modernos :
Se garantiza que esta función no ejecutará ningún código JavaScript como efecto secundario. Se ignorarán las etiquetas HTML, solo se devolverá el contenido de texto.
Nota de compatibilidad : el análisis de HTML
DOMParser
requiere al menos Chrome 30, Firefox 12, Opera 17, Internet Explorer 10, Safari 7.1 o Microsoft Edge. Por lo tanto, todos los navegadores sin soporte han superado su EOL y, a partir de 2017, los únicos que todavía se pueden ver en la naturaleza en ocasiones son versiones anteriores de Internet Explorer y Safari (por lo general, estas aún no son lo suficientemente numerosas como para molestar).fuente
DOMParser
no era compatible"text/html"
antes de Firefox 12.0, y todavía hay algunas versiones más recientes de navegadores que ni siquiera son compatiblesDOMParser.prototype.parseFromString()
. Según su referencia,DOMParser
sigue siendo una tecnología experimental, y los sustitutos usan lainnerHTML
propiedad que, como también señaló en respuesta a mi enfoque , tiene esta vulnerabilidad XSS (que los vendedores del navegador deberían corregir).<script>
etiquetas que no se ejecutan no son un mecanismo de seguridad, esta regla simplemente evita los complicados problemas de sincronización si la configuracióninnerHTML
puede ejecutar scripts síncronos como efecto secundario. Desinfectar el código HTML es un asunto complicado yinnerHTML
ni siquiera lo intenta, ya que la página web en realidad podría tener la intención de configurar controladores de eventos en línea. Esto simplemente no es un mecanismo destinado a datos inseguros, punto final.Si estás usando jQuery:
De lo contrario, utilice el Objeto codificador de Strictly Software , que tiene una
htmlDecode()
función excelente .fuente
El truco consiste en utilizar el poder del navegador para decodificar los caracteres HTML especiales, pero no permitir que el navegador ejecute los resultados como si fuera html real ... Esta función utiliza una expresión regular para identificar y reemplazar caracteres HTML codificados, un carácter a la vez
fuente
/\&#?[0-9a-z]+;/gi
ya que # solo debería aparecer como el segundo carácter, si es que lo hace.La respuesta de CMS funciona bien, a menos que el HTML que desea eliminar sea muy largo, más de 65536 caracteres. Porque luego, en Chrome, el HTML interno se divide en muchos nodos secundarios, cada uno con una longitud máxima de 65536, y debe concatenarlos. Esta función también funciona para cadenas muy largas:
Consulte esta respuesta sobre la
innerHTML
longitud máxima para obtener más información: https://stackoverflow.com/a/27545633/694469fuente
No es una respuesta directa a su pregunta, pero ¿no sería mejor para su RPC devolver alguna estructura (ya sea XML o JSON o lo que sea) con esos datos de imagen (URL en su ejemplo) dentro de esa estructura?
Luego, podría analizarlo en su javascript y construirlo
<img>
usando el propio javascript.La estructura que recibe de RPC podría verse así:
Creo que es mejor de esta manera, ya que inyectar un código que proviene de una fuente externa en su página no parece muy seguro. Imagine a alguien secuestrando su script XML-RPC y poniendo algo que no querría allí (incluso algunos javascript ...)
fuente
htmlDecode("<img src='myimage.jpg'><script>alert('xxxxx');</script>")
y no pasó nada. Obtuve la cadena html decodificada de nuevo como se esperaba.La respuesta de Chris es agradable y elegante, pero falla si el valor no está definido . Solo una mejora simple lo hace sólido:
fuente
return (typeof value !== 'string') ? '' : $('<div/>').html(value).text();
De nada ... solo un mensajero ... el crédito completo va a ourcodeworld.com, enlace a continuación.
Crédito completo: https://ourcodeworld.com/articles/read/188/encode-and-decode-html-entities-using-pure-javascript
fuente
Esta es la solución más completa que he probado hasta ahora:
fuente
Estaba lo suficientemente loco como para pasar y hacer esta función que debería ser bonita, si no completamente, exhaustiva:
Usado así:
Huellas dactilares:
Ich Heiße David
PD: esto tomó como una hora y media para hacer.
fuente
Para eliminar las entidades HTML * en JavaScript, puede usar la pequeña biblioteca html-escaper :
npm install html-escaper
O
unescape
funciona desde Lodash o Underscore , si lo estás usando.*) Tenga en cuenta que estas funciones no cubren todas las entidades HTML, pero sólo los más comunes, es decir
&
,<
,>
,'
,"
. Para unescape todas las entidades HTML que puede utilizar él biblioteca.fuente
Lo uso en mi proyecto: inspirado en otras respuestas pero con un parámetro extra seguro, puede ser útil cuando se trata de personajes decorados
Y se puede usar como:
fuente
Todas las otras respuestas aquí tienen problemas.
Los métodos document.createElement ('div') (incluidos los que usan jQuery) ejecutan cualquier javascript pasado (un problema de seguridad) y el método DOMParser.parseFromString () recorta los espacios en blanco. Aquí hay una solución javascript pura que no tiene ningún problema:
TextArea se usa específicamente para evitar ejecutar código js. Pasa estos:
fuente
htmlDecode("</textarea><img src=x onerror=alert(1)>")
. Usted publicó esto después de que ya señalé este problema en la respuesta de Sergio Belevskij.fuente
Hay una variante que es 80% tan productiva como las respuestas en la parte superior.
Vea el punto de referencia: https://jsperf.com/decode-html12345678/1
Si necesita dejar etiquetas, elimine las dos
.replace(...)
llamadas (puede dejar la primera si no necesita scripts).fuente
decodeEntities("</textarea '><img src=x onerror=alert(1) \">")
a Firefox. Deje de intentar desinfectar el código HTML con expresiones regulares.