AJAX: Usabilidad Interactiva con Código Remoto

baluart13 Octubre 2005 - 2:17pm 4 comentarios
Enviar por Email Imprimir

Desde hace buen tiempo ya, he tenído en mente publicar la traducción de un artículo escrito por Cameron Adams en SitePoint.

Probablemente sea el mejor artículo que haya leido sobre ajax, es una introducción que explica como crear el objeto xmlhttprequest e implementarlo. Asi que con las disculpas anticipadas por los horrores de gramática, publico la traducción de la primera parte del artículo: Ajax: Usable Interactivity with Remote Scripting.

Si sus marcadores (favoritos) contienen un blog de desarrollo Web, sabrá indudablemente que el scripting remoto es el "futuro de la Web".

Aunque tengo la sensación de que algunas personas están poco emocionadas sobre el reciente lanzamiento de los numerosos usos de aplicaciones Web que utilizan scripting remoto, se ha demostrado que hay ventajas bien definidas en utilizar estas técnicas en la creación de aplicaciones, aumentando la funcionalidad de la página Web.

Este artículo apunta a brindarte una introducción a los fundamentos de scripting remoto, y en particular, del emergente protocolo XMLHttpRequest. Por lo que procederemos, mediante el uso de de un ejemplo que demuestre cómo poner este protocolo en ejecución, a crear una interfaz usable.

Para comenzar, descargue el código fuente, que contiene todos los archivos que usted necesitará para crear los ejemplos de trabajo presentados aquí.

Qué es Scripting Remoto?

Esencialmente, Scripting Remoto permite que el JavaScript del lado del cliente solicite datos del servidor sin necesidad de recargar la página web. Eso es. Todo lo demás que viene con la fabricación de estas aplicaciones Web trata sobre los métodos establecidos para manipular el modelo del objeto del documento. Esto podría ser algo tan simple como la creación de una lista de palabras para seleccionar, como Google Suggest. O podría implicar la creación de una completa interfaz para navegar imágenes de mapas, como en map.search.ch.

Scripting Remoto y Accesibilidad

Como cualquier página web, siempre debemos tener en cuenta las necesidades de los usuarios. Algunos de éstos pueden tener navegadores que carecen de capacidades JavaScript, o incluso, si ellos pueden ejecutar JavaScript, no pueden tener capacidades de scripting remoto.

Esta es una de las mejores prácticas generalmente aceptadas que el JavaScript interactivo y las funciones de scripting remoto añaden a la función básica de contenido de la Web: El contenido todavía debe ser accesible y utilizable sin estas tecnologías. De no ser posible, se debe proporcionar un sistema completamente diferente para los usuarios que no cuenten con JavaScript o capacidades de scripting remoto. El equipo de GMAIL recientemente puso en práctica el interfaz alternativo al servicio, sin el uso de JavaScript.

Scripting Remoto usando XMLHttpRequest

Aunque XMLHttpRequest no es un estándar público, la mayoría de los navegadores modernos lo ponen en práctica coherentemente, y está bien en la mira de convertirse de hecho en el estándar para la recuperación de datos JavaScript. IE5 para Windows, Mozilla 1.0, el Safari 1.2 y la versión 8.0 de Ópera presentan XMLHttpRequest como un objeto disponible.

El API XMLHttpRequest de Internet Explorer esta disponible para descargar.
También puedes descargar la documentación de Mozilla.

Si requieres soporte para navegadores más viejos que estos, los métodos que usan iframes proporcionan una solución viable; sin embargo, codificando para estos navegadores también limitamos la capacidad de utilizar el método estándar JavaScript DOM. Este artículo se enfocará en el método más reciente de XMLHttpRequest.

Crear el objeto de XMLHttpRequest

En cualquier navegador, excepto IE, podemos crear un objeto XMLHttpRequest con esto:

var requester = new XMLHttpRequest();

 Sin embargo, en IE (Internet Explorer), XMLHttpRequest es implementado como un objeto ActiveX. Por lo que es creado con:

var requester = new ActiveXObject("Microsoft.XMLHTTP");

Nota: Esto también significa que si los usuarios inhabilitan los objetos ActiveX de IE, no podrán usar XMLHttpRequest, incluso si esta habilitado JavaScript.

Para hacer frente a las diferentes sintaxis de creación del objeto en los navegadores, lo mejor es utilizar una estructura try/catch para proveer automáticamente el objeto correcto, o devolver un error si el objeto XMLHttpRequest no esta habilitado:

try
{
var requester = new XMLHttpRequest();
}
catch (error)
{
try
{
var requester = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (error)
{
return false;
}
}

Gracias, la diferencia en la implementación termina ahí, y todas las siguientes llamadas al objeto XMLHttpRequest pueden ser independientes del navegador en el que se están ejecutando.

Transporte de datos usando un objeto de XMLHttpRequest

Una vez que el objeto XMLHttpRequest haya sido creado, debemos llamar dos métodos por separado para obtener los datos del servidor.

open() inicia la conexión que deseamos hacer, y toma dos argumentos, con varias opciones. El primer argumento es el tipo de petición que deseamos enviar; el segundo argumento identifica la localización de la cual deseamos requerir los datos. Por ejemplo, si deseamos utilizar GET para acceder a un feed.xml en la raíz de nuestro servidor iniciamos el objeto XMLHttpRequest con lo siguiente:

requester.open("GET", "/feed.xml");

La URL puede ser relativa o absoluta, pero debido a preocupaciones de seguridad cross-domain, el target debe residir en el mismo dominio que la página de peticiones que lo requiere.

El método open() también toma una tercera opción, argumentos booleanos que especifican si la petición esta hecha de manera asynchronously (true , es por defecto) ó synchronously (false). Con la petición synchronously, el navegador se congelará rechazando cualquier interacción del usuario, hasta que el objeto haya terminado. Una petición asynchronously ocurre en el fondo, permitiendo que funcionen otros scripts y que el usuario continúe teniendo acceso a su navegador. Se recomienda utilizar peticiones asynchronously; de lo contrario, correremos el riesgo que el navegador del usuario se trabe mientras se espera la respuesta a la petición que fue hecha. Las opciones 4 y 5 de open() son un Nombre de Usuario y una Contraseña para la autenticación al acceder a una URL protegida con contraseña.

Una vez que open() haya iniciado la conexión, el método send() activará la conexión y hará la petición. send() tomará un argumento, permitiendo que enviemos datos extras, como variables CGI, junto con la llamada. Internet Explorer lo trata de manera opcional, pero Firefox devolverá un error si no se pasa ningún valor, así que es más seguro llamarlo usando:

requester.send(null);

Para enviar variables CGI usando el método GET tenemos que escribir las variables en el open() URL.

requester.open("GET", "/query.cgi?name=Bob&email=bob@example.com");
requester.send(null);

Para enviar CGI variables usando el método POST, las variables CGI pueden ser pasadas al método send() de esta manera:

requester.open("POST", "/query.cgi");
requester.send(name=Bob&email=bob@example.com);

Una vez que hemos llamado a send(), XMLHttpRequest contactará al servidor y recuperará los datos que solicitamos; sin embargo, este proceso toma un tiempo indefinido. Para identificar cuando el objeto a recuperado los datos, debemos utilizar un evento listener. En el caso de un objeto XMLHttpRequest necesitamos escuchar los cambios en su variable readyState. Esta variable especifica el estado de la conexión del objeto y puede ser cualquiera de las siguientes:

0 – Sin iniciar
1 - Cargando
2 - Cargado
3 - Interactivo
4 - Terminado

Los cambios en la variable readyState pueden ser monitorizados utilizando un especial listener onreadystatechange, por lo que necesitamos iniciar una función para manejar el evento cuando readyState sea cambiado.

requester.onreadystatechange = stateHandler;

ReadyState incrementa desde 0 a 4 y el onreadystatechange se acciona para cada incremento, pero nosotros solamente lo deseamos cuando la conexión haya terminado (4), por lo que nuestra función necesita realizar esto. Sobre la conclusión de la conexión también tenemos que comprobar si el objeto de XMLHttpRequest recuperará con éxito los datos, o nos retornará un mensaje de error como 404: "Page not found". Esto se puede determinar de las propiedades de estado del objeto, que contiene un código de número entero. “200” denota una terminación aceptada, pero este valor puede ser cualquiera de los códigos HTTP que los servidores devuelven. Si la petición no fue acertada, debemos especificar una línea de conducta para nuestro programa:

function stateHandler()
{
if (requester.readyState == 4)
{
if (requester.status == 200)
{
success();
}
else
{
failure();
}
}

return true;
}

Aunque el objeto XMLHttpRequest permite que llamemos open() al método de los tiempos múltiples, cada objeto puede realmente ser usado para una llamada, pues el onreadystatechange no se actualiza otra vez cuando readyState cambia a 4 (en Mozilla). Por lo tanto debemos crear un nuevo objeto de XMLHttpRequest cada vez que deseamos hacer una llamada Remota.

Parseando (Analizando) los datos en un Objeto XMLHttpRequest

Si hemos hecho una petición correcta, dos características del objeto de XMLHttpRequest pueden contener datos:

  • responseXML almacena un objeto DOM-estructurado de cualquier dato XML que fuera recuperado por el objeto. Este objeto es navegable usando el standard JavaScript DOM access methods and properties, por ejemplo getElementsByTagName(), childNodes[ ] y parentNode.
  • responseText almacena los datos como un complet string. Si el tipo contenido de los datos provistos por el servidor son texto plano o texto html, entonces ésta es la única propiedad que contendrá datos. Una copia de cualquier dato de text/xml será aplanada y puesta aquí como alternativa a responseXML.

Dependiendo de la complejidad de los datos, puede ser más fácil devolver datos simples como secuencia de texto plano, de tal modo haciendo el XML en XMLHttpRequest redundante. Sin embargo, para tipos de datos más complejos, usted deseará probablemente utilizar un formato de XML, como este:

<?xml version="1.0" ?>
<user>
<name>John Smith</name>
<email>john@smith.com</email>
</user>

Podemos tener acceso a diversas partes de los datos usando los Métodos de Acceso Estándares de DOM. Recuerde que los datos contenidos entre las etiquetas son considerados como los nodos del texto niño del padre, así que nosotros tenemos que tomar esa capa adicional de estructura en cuenta cuando recuperamos los datos:

var nameNode = requester.responseXML.getElementsByTagName("name")[0];
var nameTextNode = nameNode.childNodes[0];
var name = nameTextNode.nodeValue;

Debemos también tener cuidados de los espacios en blanco: mellar valores en el XML puede producir el indeseado espacio en blanco en el valor, o agregar nodos de texto adicional.

Una vez que hemos analizado los datos del objeto de XMLHttpRequest, somos libres de cambiarlo, suprimirlo y escribirlo en nuestra página de Web como nosotros lo veamos idóneo.

El ejemplo de una Aplicación de Scripting Remoto

Para demostrar como utilizar el protocolo de XMLHttpRequest dentro de un uso scripting remoto, he creado una simpleza, una página Web de ejemplo. Esta asume que el Javascript y XMLHttpRequest están disponibles para hacer el código más legible, pero en cualquier aplicación del mundo real, usted siempre debe comprobar que XMLHttpRequest está disponible y tener un fallback (por ejemplo, un formulario de envío) donde no está disponible.

El uso del ejemplo permitirá al usuario enviar una ecard gratuitamente a la dirección de correo electrónico de un amigo. Para hacer esto, el usuario primero tiene que ingresar el número de recibo, el que recibió cuando compró bienes previamente, y que desde entonces ha sido almacenado en la base de datos de ExampleCo. Luego, el usuario debe completar los campos restantes antes de que el ecard sea enviado, escribiendo la dirección de correo electrónico del recipiente, el mensaje, y la imagen gráfica que será usada para la tarjeta:

El scripting remoto se utiliza para tres acciones en este ejemplo:

  • Reducir al mínimo el tiempo de espera para la validación del número del recibo
  • Automatizar la entrada de datos recuperados en el formulario una vez que se haya validado un número del recibo
  • Rescribir el contenido de la página una vez que el ecard se haya enviado con éxito

Junto con estas acciones, el ejemplo contiene el Javascript que valida los otros campos del formulario antes de enviarlo, y permite que el usuario seleccione un gráfico del ecard.

El ejemplo se ha creado en dos versiones distintas. La primera de estas versiones demuestra la puesta en práctica del protocolo de XMLHttpRequest dentro de una aplicación, pero contiene varios problemas de usabilidad. Estos problemas se abordan en el segundo ejemplo, que destaca algunas cosas que pueden encontrarse conforme usted se traslada de un modelo basado por página de aplicación hacia un ambiente más dinámico e interactivo.

Segunda parte de este artículo, en donde se explica como implementar paso a paso el formulario para el envío de e-cards: AJAX: Usabilidad Interactiva con Código Remoto (2da Parte).

Comentarios

Imagen de Daniel

Excelente artículo, de lo mas completo que hay hoy en día por la red (y en español!). Sus 3 capítulos me han aclarado bastantes conceptos a pesar de que ya vengo trabajando con esta tecnología. Felicitaciones al traductor y un gran saludo.

Imagen de rt
Imagen de diseño web
Imagen de Anonymous
Anonymous

muchas gracias! llevo buscando tutoriales de ajax y y sus conexiones con los navegadores.. miles y miles de horas!

gracias!

Tutoriales

Cómo descargar videos de VK.com
En este artículo voy a explicar como descargar videos y películas...
Descargar Facebook Móvil Gratis
Por si aún no lo han hecho, es posible descargar Facebook Móvil...
Cómo generar tráfico web con las redes sociales - Paso a Paso
Muchas empresas están publicando contenidos como la forma de crear...

Artículo Recomendado

3 Tips cruciales para recuperar archivos eliminados
¿Te imaginas perder el trabajo de toda una semana en tan solo unos segundos? Todos hemos pasado por este problema. Quizás eliminamos por error un archivo importante o lo borramos sin pensar que era valioso para otro... más