javascript - characters - js escape()
¿Cómo puedo escapar de algunos html en javascript? (8)
Dado el texto
<b>This is some text</b>
Quiero escribirlo en mi página para que se muestre así:
<b>This is some text</b>
y no asi
Este es un texto
usar escape("<b>This is some text</b>")
me da esta preciosa joya en Firefox
%3Cb%3EThis%20is%20some%20text%3C/b%3E
No es exactamente lo que busco. ¿Algunas ideas?
Escape tradicional
Si está utilizando XHTML, deberá utilizar una sección CDATA
. También puede usarlos en HTML, pero HTML no es tan estricto.
Divido las constantes de cadena para que este código funcione en línea en XHTML dentro de bloques CDATA. Si está comprando su JavaScript como archivos separados, entonces no necesita preocuparse por eso. Tenga en cuenta que si está utilizando XHTML con JavaScript en línea, entonces debe incluir su código en un bloque CDATA, o parte de esto no funcionará. Te encontrarás con errores extraños y sutiles.
function htmlentities(text) {
var escaped = text.replace(//]/]>/g, '']]'' + ''>]]><'' + ''![CDATA['');
return ''<'' + ''![CDATA['' + escaped + '']]'' + ''>'';
}
Nodo de texto DOM
La forma "adecuada" de escapar del texto es usar la función DOM document.createTextNode
. Esto realmente no escapa al texto; simplemente le dice al navegador que cree un elemento de texto, que es inherentemente sin analizar. Sin embargo, debe estar dispuesto a usar el DOM para que este método funcione: es decir, tiene métodos de uso como appendChild
, en oposición a la propiedad innerHTML
y similares. Esto llenaría un elemento con ID y an-element
con texto, que no se analizaría como (X) HTML:
var textNode = document.createTextNode("<strong>This won''t be bold. The tags " +
"will be visible.</strong>");
document.getElementById(''an-element'').appendChild(textNode);
jQuery DOM Wrapper
jQuery proporciona un útil envoltorio para createTextNode
llamado text
. Es muy conveniente. Aquí está la misma funcionalidad usando jQuery:
$(''#an-element'').text("<strong>This won''t be bold. The tags will be " +
"visible.</strong>");
Aquí hay una función que reemplaza los paréntesis angulares con sus entidades html. Es posible que desee expandirlo para incluir otros caracteres también.
function htmlEntities( html ) {
html = html.replace( /[<>]/g, function( match ) {
if( match === ''<'' ) return ''<'';
else return ''>'';
});
return html;
}
console.log( htmlEntities( ''<b>replaced</b>'' ) ); // <b>replaced</b>
Esto debería funcionar para usted: http://blog.nickburwell.com/2011/02/escape-html-tags-in-javascript.html
function escapeHTML( string )
{
var pre = document.createElement(''pre'');
var text = document.createTextNode( string );
pre.appendChild(text);
return pre.innerHTML;
}
Advertencia de seguridad
La función no escapa de comillas simples y dobles, que si se usa en el contexto incorrecto, aún puede conducir a XSS. Por ejemplo:
var userWebsite = ''" onmouseover="alert(/'gotcha/')" "'';
var profileLink = ''<a href="'' + escapeHtml(userWebsite) + ''">Bob</a>'';
var div = document.getElemenetById(''target'');
div.innerHtml = profileLink;
// <a href="" onmouseover="alert(''gotcha'')" "">Bob</a>
Gracias a buffer por señalar este caso. Fragmento sacado de esta entrada de blog .
Me gusta la respuesta de @ limc para situaciones donde el documento HTML DOM está disponible.
Me gustan las respuestas de @Michele Bosi''s y @ Paolo para un entorno de documento DOM no HTML como Node.js.
La respuesta de @Michael Bosi se puede optimizar eliminando la necesidad de llamar a reemplazar 4 veces con una sola invocación de reemplazo combinada con una función de reemplazo inteligente:
function escape(s) {
return s.replace(/[&"<>]/g, function (c) {
return {
''&'': "&",
''"'': """,
''<'': "<",
''>'': ">"
}[c];
});
}
console.log(escape("<b>This is some text.</b>"));
La prueba de rango de @Paolo se puede optimizar con una expresión regular bien elegida y el bucle for se puede eliminar usando una función de reemplazo:
function escape(s) {
return s.replace(/[^0-9A-Za-z ]/g, function(c) {
return "&#" + c.charCodeAt(0) + ";";
} );
}
console.log(escape("<b>This is some text</b>"));
Como lo indicó @Paolo, esta estrategia funcionará para más escenarios.
Pruebe este htmlentities para javascript
function htmlEntities(str) {
return String(str).replace(/&/g, ''&'').replace(/</g, ''<'').replace(/>/g, ''>'').replace(/"/g, ''"'');
}
Puedes codificar todos los caracteres en tu cadena:
function encode(e){return e.replace(/[^]/g,function(e){return"&#"+e.charCodeAt(0)+";"})}
O simplemente apunte a los personajes principales para preocuparse (&, inebreaks, <,>, "y '') como:
function encode(r){
return r.replace(/[/x26/x0A/<>''"]/g,function(r){return"&#"+r.charCodeAt(0)+";"})
}
test.value=encode(''Encode HTML entities!/n/n"Safe" escape <script id=/'/'> & useful in <pre> tags!'');
testing.innerHTML=test.value;
/*************
* /x26 is &ersand (it has to be first),
* /x0A is newline,
*************/
<textarea id=test rows="9" cols="55"></textarea>
<div id="testing">www.WHAK.com</div>
Terminé haciendo esto:
function escapeHTML(s) {
return s.replace(/&/g, ''&'')
.replace(/"/g, ''"'')
.replace(/</g, ''<'')
.replace(/>/g, ''>'');
}
Utilizo la siguiente función que escapa a todos los caracteres con el & # nnn ; Notación excepto az AZ 0-9 y espacio.
function Escape( s )
{
var h,
i,
n,
c;
n = s.length;
h = '''';
for( i = 0; i < n; i++ )
{
c = s.charCodeAt( i );
if( ( c >= 48 && c <= 57 )
||( c >= 65 && c <= 90 )
||( c >= 97 && c <=122 )
||( c == 32 ) )
{
h += String.fromCharCode( c );
}
else
{
h += ''&#'' + c + '';'';
}
}
return h;
}
Ejemplo:
Escape(''<b>This is some text</b>'')
devoluciones
<b>This is some text</b>
La función es la inyección de código, prueba de ataques, prueba de Unicode, JavaScript puro.
Este enfoque es aproximadamente 50 veces más lento que el que crea el nodo de texto DOM, pero aún así la función escapa a una cadena de un milion (1,000,000) en 100-150 milisegundos.
(Probado en MacBook Pro a principios de 2011 - Safari 9 - Mavericks)