Alternativa a iFrames con HTML5

196

Me gustaría saber si hay una alternativa a iFrames con HTML5. Quiero decir con eso, ser capaz de inyectar HTML de dominios cruzados dentro de una página web sin usar un iFrame.

stemlaur
fuente

Respuestas:

96

Básicamente hay 4 formas de incrustar HTML en una página web:

  • <iframe>El contenido de un iframe vive completamente en un contexto separado que su página. Si bien esa es principalmente una gran característica y es la más compatible entre las versiones del navegador, crea desafíos adicionales (reducir el tamaño del marco al contenido es difícil, increíblemente frustrante para el script dentro / fuera, casi imposible de diseñar).
  • AJAX . Como lo demuestran las soluciones que se muestran aquí, puede usar el XMLHttpRequestobjeto para recuperar datos e inyectarlos en su página. No es ideal porque depende de las técnicas de secuencias de comandos, lo que hace que la ejecución sea más lenta y compleja, entre otros inconvenientes .
  • Hacks . Pocos se mencionan en esta pregunta y no son muy confiables.
  • Componentes web HTML5 . Las importaciones HTML, parte de los componentes web, permiten agrupar documentos HTML en otros documentos HTML. Eso incluye HTML, CSS, JavaScripto cualquier otra cosa de un .htmlarchivo puede contener. Esto lo convierte en una gran solución con muchos casos de uso interesantes: dividir una aplicación en componentes agrupados que puede distribuir como bloques de construcción, administrar mejor las dependencias para evitar la redundancia, la organización del código, etc. Aquí hay un ejemplo trivial:

    <!-- Resources on other origins must be CORS-enabled. -->
    <link rel="import" href="http://example.com/elements.html">
    

La compatibilidad nativa sigue siendo un problema, pero puede usar un polyfill para que funcione en los navegadores de hoja perenne de hoy.

Puedes aprender más aquí y aquí .

Oriol
fuente
3
Los componentes web HTML5 son interesantes.
Krishna Srihari
1
Sé que esta publicación es un poco antigua, pero solo quiero comentar: en referencia a AJAX, "No es una idea porque se basa en técnicas de secuencias de comandos" ... Entonces, ¿qué hay de malo en usar secuencias de comandos? AJAX es el líder indiscutible de estas opciones y se está convirtiendo rápidamente en el estándar.
nmg49
11
Desafortunadamente, HTML Imports es una característica obsoleta ahora. developer.mozilla.org/en-US/docs/Web/Web_Components/…
Gman
¿Alguna nueva forma de lograr esto?
Walter
Otro inconveniente crucial con iFrames es el hecho de que hay muchos sitios web que han establecido 'X-Frame-Options' en 'sameorigin' y luego simplemente rechazan la conexión. En este caso, su iFrame permanece vacío. No hay forma de arreglar eso.
Igor P.
61

Puede usar objeto e incrustar, así:

<object data="http://www.web-source.net" width="600" height="400">
    <embed src="http://www.web-source.net" width="600" height="400"> </embed>
    Error: Embedded data could not be displayed.
</object>

Lo cual no es nuevo, pero aún funciona. Sin embargo, no estoy seguro de si tiene la misma funcionalidad.

nate
fuente
Gracias montones, me ahorró cargar el SDK para Facebook como caja.
Techagesite
51

No, no hay un equivalente. El <iframe>elemento sigue siendo válido en HTML5. Dependiendo de la interacción exacta que necesite, puede haber diferentes API. Por ejemplo, existe el postMessagemétodo que le permite lograr la interacción de JavaScript entre dominios. Pero si desea mostrar contenido HTML de dominio cruzado (diseñado con CSS y hecho interactivo con JavaScript) iframesigue siendo una buena manera de hacerlo.

Darin Dimitrov
fuente
3
Necesito cargar contenido de google. pero google no puede ser iframed, cuál es la alternativa.
Mike
17
@ Mike, la alternativa sería usar la API para el servicio que le gustaría usar. Google proporciona API RESTful para la mayoría de sus servicios.
Darin Dimitrov
45

object es una alternativa fácil en HTML5:

<object data="https://blogs.claritycon.com/blog/2016/03/bower-packages-asp-net-core-1-0/" width="400" height="300" type="text/html">
    Alternative Content
</object>

También puedes probar embed:

<embed src="https://blogs.claritycon.com/blog/2016/03/bower-packages-asp-net-core-1-0/" width=200 height=200 onerror="alert('URL invalid !!');" />

Abrar Jahin
fuente
44
ambos no pasan por alto los problemas que tengo con los iframes, como las políticas de seguridad
SeanMC
3
Tenga en cuenta que la mayoría de los navegadores modernos han desaprobado y eliminado la compatibilidad con los complementos del navegador, por lo que confiar en <embed> generalmente no es aconsejable si desea que su sitio funcione en el navegador del usuario promedio.
Neeraj
20

Si desea hacer esto y controlar el servidor desde el que se sirve la página base o el contenido, puede usar Cross Origin Resource Sharing ( http://www.w3.org/TR/access-control/ ) para permitir que el cliente- JavaScript lateral para cargar datos en una <div>vía XMLHttpRequest():

// I safely ignore IE 6 and 5 (!) users
// because I do not wish to proliferate
// broken software that will hurt other
// users of the internet, which is what
// you're doing when you write anything
// for old version of IE (5/6)
xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
  if(xhr.readyState == 4 && xhr.status == 200) {
    document.getElementById('displayDiv').innerHTML = xhr.responseText;
  }
};
xhr.open('GET', 'http://api.google.com/thing?request=data', true);
xhr.send();

Ahora, para el eje de toda esta operación, debe escribir código para su servidor que les dará a los clientes el Access-Control-Allow-Originencabezado, especificando a qué dominios desea que pueda acceder el código del lado del cliente XMLHttpRequest(). El siguiente es un ejemplo de código PHP que puede incluir en la parte superior de su página para enviar estos encabezados a los clientes:

<?php
  header('Access-Control-Allow-Origin: http://api.google.com');
  header('Access-Control-Allow-Origin: http://some.example.com');
?>
L0j1k
fuente
8

Un iframe sigue siendo la mejor manera de descargar contenido visual entre dominios. Con AJAX ciertamente puede descargar el HTML de una página web y pegarlo en un div (como otros han mencionado), sin embargo, el mayor problema es la seguridad. Con los iframes podrás cargar el contenido de dominio cruzado pero no podrás manipularlo ya que el contenido no te pertenece realmente. Por otro lado, con AJAX ciertamente puede manipular cualquier contenido que pueda descargar, pero el servidor del otro dominio debe configurarse de tal manera que le permita descargarlo para comenzar. Muchas veces no tendrá acceso a la configuración del otro dominio e incluso si lo hace, a menos que haga ese tipo de configuración todo el tiempo, puede ser un dolor de cabeza. En cuyo caso, el iframe puede ser la alternativa MUCHO más fácil.

Como otros han mencionado, también puede usar la etiqueta de inserción y la etiqueta de objeto, pero eso no es necesariamente más avanzado o más nuevo que el iframe.

HTML5 se ha orientado más hacia la adopción de API web para obtener información de dominios cruzados. Por lo general, las API web solo devuelven datos y no HTML.

Adán
fuente
1
No es realmente una respuesta, pero ciertamente es unnice-to-know
Stef Geysels
4

Puede usar un XMLHttpRequest para cargar una página en un div (o cualquier otro elemento de su página realmente). Una función de ejemplo sería:

function loadPage(){
if (window.XMLHttpRequest){
    // code for IE7+, Firefox, Chrome, Opera, Safari
    xmlhttp=new XMLHttpRequest();
}else{
    // code for IE6, IE5
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}

xmlhttp.onreadystatechange=function(){
    if (xmlhttp.readyState==4 && xmlhttp.status==200){
        document.getElementById("ID OF ELEMENT YOU WANT TO LOAD PAGE IN").innerHTML=xmlhttp.responseText;
    }
}

xmlhttp.open("POST","WEBPAGE YOU WANT TO LOAD",true);
xmlhttp.send();
}

Si su servidor es capaz, también puede usar PHP para hacer esto, pero como está solicitando un método HTML5, esto debería ser todo lo que necesita.

CupOfTea696
fuente
44
La mayoría de los navegadores bloquean la carga de contenido de otros dominios usando XMLHttpRequest.
Erik Terenius
44
Op está pidiendo dominios cruzados, esta respuesta no es válida.
Teoman shipahi
4

Creé un módulo de nodo para resolver este problema node-iframe-reemplazo . Proporciona la URL de origen del sitio principal y el selector CSS para inyectar su contenido y fusiona los dos.

Los cambios en el sitio principal se recogen cada 5 minutos.

var iframeReplacement = require('node-iframe-replacement');

// add iframe replacement to express as middleware (adds res.merge method) 
app.use(iframeReplacement);

// create a regular express route 
app.get('/', function(req, res){

    // respond to this request with our fake-news content embedded within the BBC News home page 
    res.merge('fake-news', {
        // external url to fetch 
       sourceUrl: 'http://www.bbc.co.uk/news',
       // css selector to inject our content into 
       sourcePlaceholder: 'div[data-entityid="container-top-stories#1"]',
       // pass a function here to intercept the source html prior to merging 
       transform: null
    });
});

La fuente contiene un ejemplo práctico de inyección de contenido en la página de inicio de BBC News .

John Doherty
fuente
0

Deberías echar un vistazo a JSON-P: esa fue una solución perfecta para mí cuando tuve ese problema:

https://en.wikipedia.org/wiki/JSONP

Básicamente, define un archivo javascript que carga todos sus datos y otro archivo javascript que lo procesa y lo muestra. Eso elimina la fea barra de desplazamiento de los iframes.

Mathias Bader
fuente