CodeForge

JavaScript de Cero a Experto / DOM a fondo

Contenido: textContent vs innerHTML

Teoría18 min20 XP

Ya seleccionas cualquier elemento; ahora vas a reescribir lo que hay adentro. Hay dos herramientas — una escribe texto, la otra construye HTML — y elegir mal entre ellas no es un error de estilo: es el agujero de seguridad más famoso de la web.

El marcador y el mini-plano

Verlo lado a lado

Compara las dos cajas de la vista previa: mismo string, resultados distintos. Y fíjate en el detalle final: LEER textContent de un elemento con HTML adentro te devuelve solo el texto — útil para extraer contenido sin etiquetas.

La regla de seguridad (no negociable)

Imagina que el nombre del gasto lo escribió el usuario en un formulario, y tu código hace elemento.innerHTML = nombreDelUsuario. Un usuario malicioso no escribe "Almuerzo": escribe una etiqueta con código adentro — y tu página la CONSTRUYE y la ejecuta. Ese ataque se llama XSS (cross-site scripting) y lleva décadas en el top de vulnerabilidades web.

la-regla.js
// ✗ NUNCA: dato del usuario directo a innerHTML
tarjeta.innerHTML = "<li>" + nombreDelUsuario + "</li>";

// ✓ SIEMPRE: el dato del usuario entra como TEXTO
item.textContent = nombreDelUsuario;

La regla completa: innerHTML es legítimo cuando TÚ escribiste el HTML que inyectas (una plantilla tuya, datos tuyos). En cuanto un pedazo del string venga de afuera — formulario, URL, API de terceros — ese pedazo entra por textContent o no entra. Sin excepciones, sin "es que era poquito".

Tu app muestra el nombre que el usuario escribió en un formulario. Un compañero propone: lista.innerHTML = '<li>' + nombre + '</li>' porque 'así queda con formato'. ¿Cuál es el problema?

Mini-reto

En "Mi Bolsillo": agrega al HTML un <p id="resumen"></p> y, desde JS, píntale un resumen con negrilla usando innerHTML y una plantilla ESCRITA POR TI (template literal con el total en <strong>). Luego simula el caso prohibido: crea una variable const nombreUsuario = "<em>hola</em>" y compárala entrando por textContent (símbolos visibles, inofensiva) vs por innerHTML (se construye). Viste el ataque con tus propios ojos: no lo olvides.

Qué sigue

Cambiar contenido de elementos que YA existen está bien, pero "Mi Bolsillo" necesita más: crear un <li> nuevo por cada gasto que se agregue. La próxima lección es la fábrica de elementos: createElement, append y compañía.