2010-05-02 26 views
14

Tengo un problema bastante interesante. Tengo una página principal que creará un diálogo de jquery modal con un iframe contenido dentro del diálogo. El iframe se completará con contenido de un dominio de terceros. Mi problema es que necesito crear un javascript de nivel de diálogo que pueda detectar si el contenido del iframe se cargó correctamente y si no lo ha hecho en un lapso de 5 segundos, luego cerrar el diálogo y devolver al usuario a la página principal.Detección de carga de contenido de iframe de dominio cruzado

He investigado numerosas soluciones y solo dos son de cierto valor.

  1. Obtenga el sitio remoto para incluir una línea de JavaScript de document.domain = 'our-domain.com'.
  2. Utilice un truco de URL Fragment, pero de nuevo necesitaría la solicitud de que el sitio remoto pueda modificar la URL agregando '#some_value' al final de la URL y mi ventana de diálogo tendría que sondear la URL hasta que o lo ve o se agota el tiempo.

¿Estas son honestamente las únicas opciones con las que tengo que trabajar? ¿No hay una forma más simple de detectar esto?

He estado investigando si hay una manera de sondear los errores de respuesta http, pero esto sigue siendo confinado a las mismas restricciones.

Cualquier ayuda sería muy apreciada.

Gracias

Respuesta

10

La manera más fácil (si puede obtener el código agregado a los sitios externos) es hacer que agreguen un iframe invisible apuntando a un archivo html especial en su dominio.Esto podría usar parent.parent.foo() para notificar a la ventana original sobre el evento de carga.

Escuchar el evento "cargar" solo le dirá si la ventana cargó, no lo que se cargó o si el documento está listo para la interacción.

+0

Esto suena como una opción definitiva. Sugeriré esto a los desarrolladores de su parte para ver si considerarán esta opción. ¡Gracias! –

+2

+1 por sugerir lo que creo que es la * única * solución para mi problema específico! Gracias. – Town

+0

Esto funciona brillantemente, aunque sorprendentemente hasta que lo piense. – Kaganar

2

Usted podría tratar de usar postMessage para la comunicación entre los marcos.
Esto requerirá que el sitio remoto incluya JavaScript específico para publicar un mensaje en el documento principal cuando haya terminado de cargarse.

+0

que pude, sí, pero que sólo funciona en IE8. Lo siento, debería haber mencionado que esta funcionalidad debe funcionar para IE 6,7 y 8 según las especificaciones de nuestro cliente. –

+0

[Anuncio desvergonzado] Hice un micro-framework para facilitar esto mientras te ayudaba a no abrir un error de seguridad en tu sitio web: https://github.com/Okrajs/Okrajs –

3

Nicholas Zakas tiene un artículo sobre la detección de si un iframe cargó: http://www.nczonline.net/blog/2009/09/15/iframes-onload-and-documentdomain/. Básicamente, usted tiene este fragmento de código:

var iframe = document.createElement("iframe"); 
iframe.src = "simpleinner.htm"; 

if (iframe.attachEvent){ 
    iframe.attachEvent("onload", function(){ 
     alert("Local iframe is now loaded."); 
    }); 
} else { 
    iframe.onload = function(){ 
     alert("Local iframe is now loaded."); 
    }; 
} 

document.body.appendChild(iframe); 

Yo no lo he probado, pero estoy bastante seguro de jQuery debe ser capaz de manejar la situación haciendo algo como $("#iframe").load(function() { alert("Local iframe is now loaded."); });

+0

Gracias por el fragmento de código. Lo intentaré y veré cómo funciona esto. –

0

En todo caso será necesario algún tipo de cooperación del servidor del otro dominio, ya que está tratando de abusar del Same Origin Policy (SOP)

La primera solución document.domain=... no funcionará si los dominios son diferentes. Funciona solo para subdominios y puertos, como se describe en el enlace de arriba.

La única opción que permite la comunicación entre dominios sin sondeo es JSONP o la inyección de scripts con una función de devolución de llamada JS. Este método está disponible en todas las API de Google y funciona bien.

Hemos explicado en our blog una forma de guardar esas llamadas en un iframe para protegerlas. Mientras que postMessage es mejor ahora, el window.name hack tiene la ventaja de trabajar en navegadores antiguos.

Irónicamente, SOP no le impide PUBLICAR nada a otro dominio. Pero no podrás leer la respuesta.

+1

Bueno, no estoy tratando de 'abusar' de la política de SOP, pero la necesidad de esto se encuentra en una etapa crítica en la actividad del usuario. Sí, necesito esto para trabajar en los navegadores mencionados anteriormente. Curiosamente, no hay otro navegador actualmente en su especificación. ¡Todavía! Voy a echar un vistazo a esos enlaces y gracias por la información adicional. –

1

Es posible hacer esto con un controlador de carga en el propio iframe. Desafortunadamente (¡sorpresa!) IE lo hace difícil. La única forma en que podía hacer que esto funcionara era componer HTML para el iframe, luego anexarlo al documento con innerHTML. Luego tengo que sondear para ver cuándo aparece el iframe en el DOM, que varía según si la página se está cargando. Aquí hay un enlace a la fuente: http://svn.openlaszlo.org/openlaszlo/trunk/lps/includes/source/iframemanager.js

Ver create(), __finishCreate() y gotload(). ¡Siéntase libre de tomar una copia de esto y usarlo usted mismo!

Saludos, Max Carlson OpenLaszlo.org

+1

Gracias por la posible solución, Max. Mi compañero de trabajo y yo hemos decidido intentar usar el método postMessage. Aunque esto no funciona para IE 6 y 7, sí encontramos que sería suficiente con nuestras necesidades inmediatas si conseguimos que el cliente acepte el uso de postMessage. Con mucho gusto examinaré su sugerencia, ya que uno nunca puede tener suficientes trucos para la manga proverbial de uno. :) –

Cuestiones relacionadas