07 agosto, 2008

Servicios Web con window.name

Hace unos días se proponía el uso de window.name para guardar información que se mantiene en una pestaña o ventana del navegador aunque se reutilice para cargar una nueva página. El navegador impide el acceso en el caso de un iframe a menos que éste mostrando una página del mismo dominio que el padre.

La gente de Dojo ha ideado un sistema de consulta de servicios web que, basado en window.name, permite saltarse de forma controlada la restricción del navegador de impedir el acceso a marcos que carguen páginas de otros dominios distintos al actual.

Eso mismo se podía hacer ya con JSONP: realizar una consulta a un servicio web de forma que la respuesta tuviese la forma callback( {"respuesta_en_json":"ok"} ) donde callback es el nombre de la función javascript a la que se le pasa la respuesta en formato JSON y que se indica al realizar la consulta.

En este caso, se utiliza un iframe para hacer la consulta al servicio y su respuesta sería similar a la siguiente:


<html><script type="text/javascript">
window.name = document.getElementsByTagName("script")[0].innerHTML.match(/temp\s*=([\w\W]*)/)[1];history.go(-1);
temp= {
    id:"4",
    lastName:"Z",
    created: new Date(1218058428000),
    nbsp; firstName:"MIKI"
}
</script></html>

Es decir, la respuesta se indica en la variable temp, que se convierte en cadena y se guarda en window.name. Inmediatamente después, se vuelve atrás en el marco (el equivalente a indicar el comando volver en el navegador) para que el dominio de la página vuelva a ser el mismo que el de la página padre y pueda así accederse a window.name.

El código de la página principal sería el siguiente:


<html>
<body>
<iframe frameborder="0" id="ifr" onload="loaded()" src="/window.name/blank.html" style="border: 1px dotted red;"></iframe>

<br /><button onclick="go()">Run...</button><br />

<div id="results" style="border: 1px dotted red;"></div>

<script type="text/javascript">
var started= false;
function loaded() {
 if (!started) return;
 started= false;
 document.getElementById('results').innerHTML= getWin().name;
}
function getWin() {
 ifr=document.getElementById('ifr');
 if (~navigator.userAgent.indexOf('MSIE')) {
  win= ifr.window;
 } else {
  win= ifr.contentWindow;
 }
 return win;
}
function go() {
 started= true;
 win= getWin();
 win.location="http://localhost/dos.html";
}
</script>
</body></html>

Al principio, el iframe contiene una página en blanco del mismo dominio que la principal (http://127.0.0.1). Cuando se pulsa el botón Run, se ejecuta la función go, que carga en el iframe el servicio solicitado (del dominio http://localhost) y al terminar de cargar se dispara el evento onload y por tanto la función loaded que ya tiene acceso a la propiedad window.name del iframe.

Éste último paso podría dar un error en caso de que la página cargada en el iframe siguiese en el dominio http://localhost, pero como al finalizar la carga vuelve atrás al dominio http://127.0.0.1, el acceso se permite.

La función getWin se utiliza para acceder a la propiedad window del iframe, ya que se hace de forma distinta en Firefox y en el IExplorer (para variar).

Publicar un comentario en la entrada

Últimos links en indiza.com