Con este título en dos partes continuamos con la serie dedicada a AJAX en donde se había quedado.

Los principales problemas que nos podemos encontrar al usar técnicas AJAX en nuestras aplicaciones Web son los siguientes:

  1. Llamadas fuera del dominio.
  2. Llamadas que producen errores o que no vuelven jamás.
  3. Envío de datos al servidor.
  4. Las malditas/benditas cachés.

En este post trataremos el primer problema y dejamos para los siguientes los restant.

Una vez que uno empieza a juguetear con las posibilidades de AJAX enseguida se nos ocurren ideas geniales para sacarle partido. La más obvia, claro está, es la de utilizar las técnicas para acceder desde el cliente a ciertos servicios web de utilidad ubicados en Internet que para eso están. Así, dado que los Servicios Web están basados en XML es muy fácil procesar lo que devuelven con las técnicas descritas para, por ejemplo, realizar búsquedas en Google o en Amazon con su API, enviar "posts" a nuestro blog, etc...

Otra aplicación es la de construir un lector de noticias RSS para, desde el navegador directamente, acceder a este tipo de fuentes de información sin necesidad decargar al servidor con su proceso previo.

Todo esto es estupendo pero tiene un gravísimo problema: los navegadores, por cuestiones de seguridad, bloquean todas las peticiones realizadas mediante XmlHttpRequest a dominios que no sean el que aloja la página desde la que se está usando.

En realidad se trata de una restricción bastante lógica y a la que otros entornos de programación como Flash o los Applets Java nos tienen acostumbrados de toda la vida. Pero esto, claro está, supone una limitación importante para ciertos tipos de aplicaciones AJAX que podríamos desarrollar, como las de los ejemplos comentados.

¿Cómo lo solucionamos?

Bueno, en Internet Explorer basta con bajar el nivel de seguridad para que ya funcione correctamente, pero no es una buena solución (no le puedes pedir esto a todos tus usuarios). En Firefox, Opera y safari no hay forma de hacerlo funcionar. Existe una salvedad en Firefox que consiste en firmar digitalmente el JavaScript que usas, pero tampoco vale de mucho pues sólo funcionaría en este navegador.

En fin, que estamos bastante fastidiados.

La única forma de solucionarlo de manera independiente al navegador es, obviously, hacer que no dependa de éste, es decir, llevándonoslo al servidor. Para ello lo que debemos hacer es construir un servicio Proxy que esté en nuestro servidor (al que sí podremos llamar con AJAX) y qué este se encargue de realziar la llamada a otros dominios devolviendo el resultado a nuestro JavaScript, directamente o, ya de paso, pre-procesádolo. En fin, que no nos libramos de trabajar en el lado servidor :-(

En .NET esto implica que lo mejor es crear un manejador de peticiones con extensión .ashx que se encargue de enrutar las peticiones que nos interesen. ¡Mucho ojo con esto!. Normalmente este tipo de servicios, al igual que los que se encargan de ller archivos de disco de manera genérica y similares, son un verdadero peligro de seguridad que puede poner en peligro todo el servidor. Si haces esto lo mejor es que tomes varias precauciones de cara a la seguridad:

  • Ten muy acotados los servicios o URLs a los que se puede llamar desde tu proxy. Lo mejor es que los identifiques a cada uno con un número o código decidiendo a cuál se llama desde un switch (o Select Case en VB.NET), nunca poniendo la URL en la llamada de tu JavaScript.
  • Trata de identificar al Script llamante de alguna manera: mediante una cabecera que te debe enviar, comprobando el dominio del "referer" y cosas similares. Está claro que el que controle se puede saltar esto sin problemas pero le das más trabajo y te elimina a los aficionados que quieran hacer uso ilícito de tu servicio.
  • Si puedes limita el número máximo de llamadas seguidas que s epuede hacer desde una determinada IP o, mejor, en una determinada sesión de servidor.

Otra opción más "de andar por casa"

Si lo de escribir un proxy no te convence o no sabes cómo hacerlo bien tienes otra opción que te permite "zafar" sin ello. consiste en usar un marco interno (IFRAME) oculto. En él cargas la URL que te interese usando su propiedad src. Al ser un marco interno tienes acceso a todas las propiedades de su document, es decir, que puedes detectar cuándo ha terminado de cargar y leer sus contenidos procesándolos también mediante DOM. Funciona pero es mucho más tedioso y propenso a errores.

Escrito por un humano, no por una IA