2008-12-17 29 views
50

Puedo detectar cuando el contenido de un iframe se ha cargado usando el evento de carga . Lamentablemente, para mi propósito, hay dos problemas con esto:Detectar error al cargar el contenido de un iframe

  • Si se produce un error al cargar la página (404/500, etc.), el evento de carga nunca se activa.
  • Si algunas imágenes u otras dependencias no se pueden cargar, el evento de carga se dispara como de costumbre.

¿Hay alguna manera de poder determinar de manera confiable si se produjo alguno de los errores anteriores?

Estoy escribiendo una aplicación semi-web semi-escritorio basada en Mozilla/XULRunner, por lo que las soluciones que solo funcionan en Mozilla son bienvenidas.

Respuesta

14

Si usted tiene control sobre la página iframe (y las páginas están en el mismo nombre de dominio), una estrategia que podría ser de la siguiente manera:

  • En el documento principal, inicializar una variable var iFrameLoaded = false;
  • Cuando el documento de iframe está cargado, establezca esta variable en el elemento primario en true llamando desde el documento iframe a la función principal (setIFrameLoaded(); por ejemplo).
  • marca iFrameLoaded utilizando el objeto timer (establezca el temporizador a su límite de tiempo de espera preferido) - si la bandera sigue siendo falsa puede indicar que el iframe no se cargó regularmente.

Espero que esto ayude.

+5

1) ¿Por qué molestarse añadir JavaScript a la página de iframe? Podría utilizar setTimeout tan fácilmente junto con el evento de carga. 2) Esto no detecta de manera confiable si falla la carga o por qué, solo si tiene éxito dentro de un límite de tiempo. 3) No detecta el caso donde las dependencias de página no se cargan. –

+0

Se cargarán diferentes recursos en diferentes marcos de tiempo. Esa imprevisibilidad matará a su enfoque Daniel Cassidy, ya que tendrá que permitir un tiempo de espera razonablemente largo. Mientras tanto, los errores de carga de corta duración simplemente se mantendrán en la pantalla hasta que el temporizador asuma que el recurso no se pudo cargar y maneja el error. – seebiscuit

8

Tuve este problema recientemente y tuve que recurrir a la configuración de una acción de Votación de Javascript en la página principal (que contiene la etiqueta IFRAME). Esta función de JavaScript comprueba el contenido de IFRAME para elementos explícitos que solo deberían existir en una respuesta BUENA. Esto supone, por supuesto, que no tiene que lidiar con la violación de la "misma política de origen".

En lugar de buscar todos los posibles errores que puedan generarse a partir de los muchos recursos de red diferentes ... simplemente verifiqué el elemento positivo constante que sé que debería estar en una buena respuesta.

Después de un tiempo predeterminado y/o # de intentos fallidos para detectar los Elementos esperados, el JavaScript modifica el atributo SRC del IFRAME (para solicitar de mi Servlet) una Página de Error fácil de usar en lugar de mostrar el típico mensaje HTTP ERROR. El JavaScript también podría modificar fácilmente el atributo SRC para hacer una solicitud completamente diferente.

function checkForContents(){ 
var contents=document.getElementById('myiframe').contentWindow.document 
if(contents){ 
    alert('found contents of myiframe:' + contents); 
    if(contents.documentElement){ 
     if(contents.documentElement.innerHTML){ 
      alert("Found contents: " +contents.documentElement.innerHTML); 
      if(contents.documentElement.innerHTML.indexOf("FIND_ME") > -1){ 
       openMediumWindow("woot.html", "mypopup"); 
      } 
     } 
    } 
} 

}

1

creo que el evento pageshow es despedido por las páginas de error. O si está haciendo esto desde Chrome, revise la solicitud de su oyente de progreso para ver si se trata de un canal HTTP, en cuyo caso puede recuperar el código de estado.

En cuanto a las dependencias de página, creo que solo se puede hacer desde Chrome agregando un detector de eventos onerror, e incluso entonces solo encontrará errores en los elementos, no en fondos CSS u otras imágenes.

0

Tiene una identificación para el elemento superior (cuerpo) en la página que se está cargando en su iframe.

en el controlador de carga de su iframe, verifique si getElementById() devuelve un valor no nulo. Si es así, iframe se ha cargado correctamente. de lo contrario, ha fallado.

en ese caso, ponga frame.src = "about: blank". Asegúrese de quitar el manejador de carga antes de hacer eso.

+0

qué ocurre si no tenemos control en la página que estamos cargando. entonces, ¿cómo manejar esta situación? –

0

No contesta su pregunta exactamente, pero mi búsqueda de una respuesta me trajo aquí, así que estoy publicando solo en caso de que alguien más me haya hecho una consulta similar.

No utiliza bastante un evento de carga, pero puede detectar si un sitio web es accesible e invocable (si lo es, entonces el iFrame, en teoría, debería cargarse).

Al principio, pensé en hacer una llamada AJAX como todos los demás, excepto que inicialmente no funcionó para mí, ya que había usado jQuery. Funciona perfectamente si lo hace un XMLHttpRequest:

var url = http://url_to_test.com/ 
var xhttp = new XMLHttpRequest(); 
xhttp.onreadystatechange = function() { 
    if (this.readyState == 4 && this.status != 200) { 
     console.log("iframe failed to load"); 
    } 
}; 
xhttp.open("GET", url, true); 
xhttp.send(); 

Editar:
Así que este método funciona bien, excepto que tiene una gran cantidad de falsos negativos (recoge una gran cantidad de cosas que mostrar en un iframe) debido a origen cruzado malarky. La forma en que resolví esto fue hacer una solicitud CURL/Web en un servidor, y luego verificar los encabezados de respuesta para a) si el sitio web existe, yb) si los encabezados habían establecido x-frame-options.

Esto no es un problema si ejecuta su propio servidor web, ya que puede hacer su propia llamada api para ello.

Mi aplicación en Node.js:

app.get('/iframetest',function(req,res){ //Call using /iframetest?url=url - needs to be stripped of http:// or https:// 
    var url = req.query.url; 
    var request = require('https').request({host: url}, function(response){ //This does an https request - require('http') if you want to do a http request 
     var headers = response.headers; 
     if (typeof headers["x-frame-options"] != 'undefined') { 
      res.send(false); //Headers don't allow iframe 
     } else { 
      res.send(true); //Headers don't disallow iframe 
     } 
    }); 
    request.on('error',function(e){ 
     res.send(false); //website unavailable 
    }); 
    request.end(); 
}); 
Cuestiones relacionadas