Inserción de contenido e iframes

A veces, lo que quieres en tu página ya existe en otro lugar: un video en YouTube, una ubicación en un mapa, un formulario de pago ejecutado por otra empresa. En lugar de reconstruirlo, puedes colocar toda esa página dentro de la tuya. El elemento que hace esto es el <iframe>, y viene con un conjunto de controles para mantener el contenido prestado dimensionado, accesible y seguro.
El elemento iframe
Un iframe inserta otra página web dentro de la tuya. El nombre es una abreviatura de "inline frame" (marco en línea), y esa es una buena representación: una pequeña ventana enmarcada en tu página, con una página completamente separada visible a través de ella. Un video de YouTube en una publicación de blog es casi siempre un iframe.
Apuntas a la página que deseas mostrar con el atributo src, el mismo atributo que usa una imagen para su archivo:
<iframe src="https://www.youtube.com/embed/aqz-KE-bpKQ"></iframe>Esa única etiqueta trae el reproductor de YouTube a tu página. Piénsalo como colgar una ventana en una pared: la pared es tu página, y a través de la ventana ves una sala completamente diferente.
Un <iframe> carga una página web separada y completa y la muestra como un rectángulo dentro de la tuya. El atributo src contiene la dirección de esa página, y todo lo dentro del marco, su propio HTML, CSS y JavaScript, se ejecuta por su cuenta, mantenido separado de tu página.
<iframe src="https://www.openstreetmap.org/export/embed.html"></iframe>Cualquier cosa que escribas entre las etiquetas de apertura y cierre es contenido de respaldo, mostrado solo por navegadores demasiado antiguos para soportar marcos, lo que en la práctica no es ninguno. El marco se configura completamente a través de sus atributos, y la siguiente sección cubre los que realmente configurarás.
Un <iframe> crea un contexto de navegación anidado: un documento completo e independiente incrustado dentro de tu documento (un contexto de navegación es el entorno en el que se ejecuta una página individual, con su propio historial, su propio ámbito global y su propia copia del DOM). El marco no forma parte del árbol DOM de tu página de ninguna manera significativa; es una página separada que sucede estar dibujada dentro de una caja en la tuya.
Esa separación es el punto clave, y se aplica mediante la política del mismo origen: tu página y la página enmarcada solo pueden leer o hacer script una a la otra si comparten un origen (un origen es la combinación de esquema, host y puerto, por lo que https://example.com y https://other.com son orígenes diferentes). Un marco del mismo origen al que puedes acceder con JavaScript mediante iframe.contentWindow; un marco de origen cruzado es una caja sellada a la que puedes apuntar pero no inspeccionar. Casi cada insertado que colocas, un video, un mapa, un widget, es de origen cruzado, que es exactamente por qué es seguro colocar en primer lugar.
<iframe> muestra toda otra página web dentro de la tuya, como una pequeña ventana que mira hacia otra sala. Apuntas a algún lugar con src, de la misma manera que lo hace una imagen. ¿Ese reproductor de YouTube en un blog? Casi siempre uno de estos. <iframe> carga una página separada y autocontenida y la muestra en una caja en la tuya. Su propio HTML, CSS y JavaScript se mantienen aislados de tu página. Lo configuras completamente a través de atributos, comenzando con src. Inserción de videos, mapas y widgets
Las buenas noticias: casi nunca escribes código de inserción a mano. El sitio desde el que estás insertando lo escribe para ti. En YouTube haces clic en Compartir, luego en Insertar, y te da un <iframe> listo para copiar. Los mapas, reproductores de música y calendarios funcionan de la misma manera. Copias su bloque y lo pegas en tu HTML.
<iframe src="https://www.youtube.com/embed/aqz-KE-bpKQ" width="560" height="315"></iframe>Los atributos width y height establecen el tamaño del marco, medido en píxeles. Cambia esos dos números y el video se hace más grande o más pequeño en tu página.
La mayoría del código de inserción viene directamente de la fuente. Busca un botón Compartir o Insertar, y el servicio te da un bloque <iframe> dimensionado y apuntado para ti. Tres atributos vale la pena entender en lugar de solo pegar:
<iframe
src="https://www.youtube.com/embed/aqz-KE-bpKQ"
width="560"
height="315"
title="Cortometraje Big Buck Bunny"
loading="lazy"
></iframe>width y height establecen el tamaño del marco en píxeles. El atributo title nombra el marco para lectores de pantalla, que lo anuncian de la manera en que anuncian el texto de un enlace, por lo que un marco sin título se lee como un "marco" sin etiquetar y no ayuda a nadie. loading="lazy" le dice al navegador que espere a descargar la página enmarcada hasta que el lector se desplace cerca de ella, lo que mantiene los insertados bajos en la página sin ralentizar la carga inicial.
Para un marco que debe estirarse para ajustarse a su contenedor en lugar de un tamaño de píxel fijo, elimina los atributos width y height y dimensiónalo con CSS, usando aspect-ratio para mantener las proporciones correctas de un video.
El fragmento de inserción que te da un servicio es un valor predeterminado razonable, no una decisión final. Algunos atributos deciden qué tan bien se comporta en producción.
<iframe
src="https://www.youtube-nocookie.com/embed/aqz-KE-bpKQ"
title="Cortometraje Big Buck Bunny"
loading="lazy"
referrerpolicy="strict-origin-when-cross-origin"
allowfullscreen
style="width: 100%; aspect-ratio: 16 / 9; border: 0;"
></iframe>title no es opcional en la práctica: la tecnología de asistencia (software como lectores de pantalla que lee la página en voz alta) trata un marco como un punto de referencia y anuncia su título, así que uno faltante deja una región en blanco en el orden de lectura. loading="lazy" aplaza la carga del documento del marco hasta que se acerca a la ventana gráfica (el área visible de la página), lo que importa mucho aquí porque cada marco es una carga de página completa, no un único activo. referrerpolicy controla cuánto de la URL de tu página se envía al servicio insertado en el encabezado Referer (el campo que un navegador adjunta para decirle a un servidor de dónde vino una solicitud), y apretarlo filtra menos sobre tus usuarios. Dimensiona de forma responsiva con aspect-ratio en lugar de píxeles fijos para que el marco se refluje en pantallas pequeñas. El hábito que vale la pena mantener: lee el fragmento antes de pegarlo, porque estás heredando los valores predeterminados que el proveedor eligió.
<iframe> para pegar. Cambia width y height para redimensionarlo. Ese es la mayoría del trabajo. title para que los lectores de pantalla puedan nombrar el marco, y loading="lazy" para que un marco más abajo en la página no ralentice la primera pintura. Para cambio de tamaño flexible, elimina el ancho y alto en píxeles y usa CSS aspect-ratio. title para el orden de lectura, loading="lazy" porque un marco es una carga de página completa y no un único activo, una referrerpolicy ajustada para que filtre menos sobre tus usuarios, y aspect-ratio para cambio de tamaño responsivo. Lee lo que pegas, ya que heredas cada valor predeterminado que eligieron. Aislamiento y permisos
Debido a que un marco ejecuta toda otra página, es posible que desees limitar lo que esa página puede hacer. El atributo sandbox hace exactamente eso: coloca el marco detrás de una cerca de seguridad.
<iframe src="widget.html" sandbox></iframe>Con sandbox por sí solo, la página enmarcada se mantiene en la configuración más estricta: no puede ejecutar sus propios scripts, enviar formularios o abrir nuevas ventanas. Luego le devuelves permisos específicos uno a la vez, solo los que el insertado realmente necesita. Piénsalo como prestar a alguien una sala pero cerrar los armarios que no quieres que se abran.
Dos atributos controlan lo que puede hacer un marco. sandbox restringe el marco, y allow otorga acceso a características de dispositivos y navegadores.
Agregar sandbox sin valor bloquea casi todo lo que la página enmarcada podría hacer: scripts, formularios, ventanas emergentes y tratarse a sí misma como del mismo origen. Lo flexibilizas listando tokens de permiso separados por espacios:
<iframe
src="https://example.com/widget"
sandbox="allow-scripts allow-forms"
></iframe>allow-scripts permite que el marco ejecute JavaScript, allow-forms permite que envíe formularios, allow-popups permite que abra nuevas ventanas. Otorga solo lo que el insertado necesita. El atributo allow separado rige características sensibles del navegador como pantalla completa, cámara y micrófono:
<iframe src="https://example.com/call" allow="camera; microphone; fullscreen"></iframe>Si una característica no aparece en allow, la página enmarcada no puede usarla, incluso si su propio código lo solicita.
Dos modelos distintos están aquí, y vale la pena mantenerlos separados. sandbox elimina capacidades del marco; allow otorga acceso a características controladas. No son dos formas de deletrear lo mismo.
sandbox sin valor aplica cada restricción a la vez: sin scripts, sin envío de formularios, sin ventanas emergentes, sin medios que se reproduzcan automáticamente, y, lo que es importante, el marco se fuerza a un origen opaco único (un origen que no coincide con nada más, por lo que el marco no puede reclamar ser del mismo origen con nadie, incluido el sitio desde el que se cargó). Devuelves capacidades con tokens:
<iframe
src="https://example.com/widget"
sandbox="allow-scripts allow-popups allow-popups-to-escape-sandbox"
></iframe>Hay una combinación que debes evitar. Otorgar tanto allow-scripts como allow-same-origin a un marco que se carga desde tu propio origen permite que la página enmarcada ejecute código que puede retroceder y eliminar su propio sandbox, lo que derrota el propósito. Solo empareja esos dos cuando el contenido del marco es completamente de confianza.
El atributo allow es una Política de Permisos (un mecanismo del navegador para decidir qué páginas pueden usar características sensibles como la cámara, micrófono, geolocalización o pantalla completa). Su valor predeterminado es denegar: una característica no nombrada en allow no está disponible para el marco sin importar qué solicite su script. Así es como colocas un widget de videollamada que necesita la cámara sin también darle esa cámara a todos los demás marcos en la página.
sandbox a un marco y bloquea la página incrustada: sin scripts, sin ventanas emergentes, sin travesuras. Luego devuelves solo los permisos que realmente necesita. Es como prestar una sala pero mantener algunos armarios cerrados. sandbox restringe un marco y lo flexibilizas token por token, como allow-scripts y allow-forms. El atributo allow separado es lo que otorga cámara, micrófono o pantalla completa. Dale a cada uno solo lo que el insertado realmente solicita. sandbox quita capacidades, allow otorga características controladas y por defecto deniega. La trampa es emparejar allow-scripts con allow-same-origin en un marco del mismo origen, ya que eso permite que la página desbloquee su propio sandbox. Solo haz eso cuando confíes completamente en lo que hay dentro. Advertencias de seguridad y rendimiento
Los insertados son convenientes, pero cada marco carga una página extra completa, así que una pila de ellos puede hacer que la tuya se sienta lenta. Dos hábitos te mantienen fuera de problemas: solo insertar desde sitios en los que confías, ya que estás invitando su página a la tuya, y no agregar más marcos de los que necesitas.
El atributo loading="lazy" de antes también ayuda aquí, reteniendo marcos hasta que el lector se desplace a ellos. Recurre a un insertado cuando ahorres trabajo real, como un video o un mapa, y omítelo cuando un enlace simple haría el mismo trabajo.
Cada marco que agregas es una carga de página completa: su propio HTML, su propio CSS, y a menudo su propio montón de JavaScript, todo descargado de otro servidor. Una página con tres insertados de terceros es realmente cuatro páginas cargando a la vez, razón por la cual las páginas con muchos insertados se sienten pesadas. loading="lazy" en marcos fuera de pantalla es la ganancia más barata, y preferir un insertado sobre tres es la siguiente.
Hay una segunda preocupación más allá de la velocidad. Puedes proteger tu propia página de ser colocada dentro del marco de alguien más, lo que detiene un truco donde un atacante enmarca tu sitio y engaña a los usuarios para hacer clic en cosas que no pueden ver. Esa protección se configura en el servidor, y el nivel avanzado cubre los dos encabezados que lo hacen.
Dos costos merecen una mirada clara. Qué hace un marco a tu rendimiento, y qué puede hacer el framing a tu seguridad.
En rendimiento, un marco de terceros no es una única solicitud; es una carga de documento anidada que ejecuta la pila completa del proveedor (su marcado, estilos, fuentes, análisis y scripts) dentro de tu página. Compite por la misma red y hilo principal, y sus scripts se ejecutan en su propio contexto pero en el mismo dispositivo, así que un insertado pesado puede retrasar que tu propio contenido se vuelva interactivo. loading="lazy" aplaza marcos fuera de pantalla, y consolidar insertados gana sobre ajustar cualquiera individual. Mide el costo real antes de asumir que un insertado es gratis.
En seguridad, el riesgo es clickjacking: un atacante carga tu página en un marco en su propio sitio, la hace invisible o la superpone, y atrae a un usuario autenticado a hacer clic en un control real en tu página sin darse cuenta. La defensa es declarar quién, si alguien, puede enmarcar tus páginas, y se configura con un encabezado de respuesta en tu servidor, no en el HTML:
X-Frame-Options: DENYse niega a permitir que tu página se cargue en ningún marco en absoluto.SAMEORIGINpermite solo que tu propio sitio la enmarque. Este es el control más antiguo y más grueso.Content-Security-Policy: frame-ancestors 'self'es el reemplazo moderno. frame-ancestors lista exactamente qué orígenes pueden enmarcar tu página (una Política de Seguridad de Contenido, o CSP, es un encabezado que le dice al navegador qué fuentes de contenido y comportamiento permitir). Reemplaza aX-Frame-Options, permite una lista de permisos específica en lugar de una regla general única, y es la que configuras en cualquier cosa con un inicio de sesión o un formulario.
Nota la dirección: sandbox y allow controlan páginas que insertas, mientras que frame-ancestors y X-Frame-Options controlan quién puede insertarte a ti. Ambas direcciones importan, y se configuran en lugares diferentes.
loading="lazy". Si un enlace simple haría el mismo trabajo, usa el enlace. loading="lazy" en marcos fuera de pantalla es la ganancia barata, y menos insertados gana sobre ajustar uno. También hay un riesgo de framing que vale la pena guardarse, que el nivel profundo cubre con dos encabezados de servidor. frame-ancestors en una CSP es el control moderno, X-Frame-Options el más antiguo. Recuerda la dirección, ya que sandbox protege páginas que insertas y frame-ancestors protege quién te inserta a ti. 
