Llamando a Web Services por medio del objeto XMLHttpRequest de Javascript.

De un tiempo a esta parte, estamos viendo como Ajax cada vez tiene más protagonismo en nuestras aplicaciones. Las razones son varias pero las que más peso tienen seguramente son:

  • La ganancia en usabilidad que proporciona.
  • Lo fácil que es trabajar de esta manera.

Actualmente, existen infinidad de Frameworks que nos facilitan la vida a la hora de trabajar con Ajax o mejor dicho con Javascript como Prototype, JQuery, Microsoft Ajax Library o Microsoft Ajax etc… Por lo tanto, es normal que proliferen este tipo de aplicaciones.

La mayoría del trabajo con Ajax pasa por el uso de llamadas asíncronas a un servidor, y esto, aunque los distintos Frameworks lo gestionen de una forma u otra, lo conseguimos gracias al objeto XMLHttpRequest.

Un poco de historia.

La interfaz XMLHttpRequest fue desarrollada por Microsoft y la lanzo con Internet Explorer 5. Esta versión se publicó utilizando un objeto ActiveX, por lo tanto podía ser utilizada en cualquier entorno de desarrollo con soporte de esta tecnología (prácticamente la totalidad de plataformas de desarrollo de Microsoft).

Posteriormente la interfaz se ha ofrecido de manera integrada tanto en Internet Explorer como en otros navegadores (Firefox desde la versión 1.0, Safari desde la 1.2, Opera desde la 8.0 etc.…) de manera que el acceso a ella se realiza por medio de objetos (Javascript, VBScript etc.…) proporcionados por los navegadores.

El 27 de septiembre de 2006, el World Wide Web Consortium presento el primer borrador de una especificación estándar.

El objeto XMLHttpRequest de Javascript.

Javascript, goza de un objeto que nos permite usar la interfaz XMLHttpRequest, así que los Frameworks anteriormente nombrados (y muchos otros), se basan en este objeto para hacer llamadas síncronas o asíncronas al servidor.

Ahora vamos a ir viendo como realizar peticiones con este objeto.

Como crear un objeto XMLHttpRequest.

Cuando queramos crear un objeto XMLHttpRequest, tendremos que hacerlo en función del navegador, porque como ya hemos visto, no todos soportan la interfaz de forma integrada, de manera que el código que necesitamos es el siguiente:

function createXmlHttpRequestObject()
{
var req = false;
if(window.XMLHttpRequest && !(window.ActiveXObject)) // branch for native XMLHttpRequest object
{
try
{
req = new XMLHttpRequest();
}
catch(e)
{
req = false;
}
}
else if(window.ActiveXObject) // branch for IE/Windows ActiveX version
{
try
{
req = new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e)
{
try
{
req = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(e)
{
req = false;
}
}
}
return req;
}

Como se puede ver en la función, preguntamos si el navegador tiene integrada la interfaz y no soporta objetos ActiveX. Este código lo implementamos para crear el objeto en navegadores como Firefox, Safari, Opera etc.. (Si no preguntaramos por el tema de la tecnología ActiveX, tambien podríamos crearlo en Internet Explorer 7, ya que este tambien la tiene integrada).

Para navegadores más antiguos (IE6, IE5 en concreto), usamos el código del else if, que nos permite crear el objeto vía ActiveX.

Una vez tenemos creado el objeto, únicamente tenemos que abrir la conexión, definir el handler que manejara la petición asincrona y enviar los parametros.

Definiendo el Handler que manejara la respuesta.

Para indicar que Handler va a manejar la respuesta, hacemos uso de la propiedad onreadystatechange de la interfaz y sería de esta manera:

request.onreadystatechange = responseHandler;

Abriendo la conexión con la url destino.

Ahora vamos a abrir la conexión, para ello usamos el metodo open, su signatura es la siguiente:

open (método, URL [, asíncrono[, nombreUsuario [, clave]]] )

Como podemos ver, como parámetros tenemos que enviarle siempre el método de envío (GET, POST o PUT) y la url a la que llamamos y como parámetros opcionales, le pasamos un booleano indicando si la petición es síncrona o asíncrona, el usuario y el password.

Un ejemplo de uso sería el siguiente:

request.open("POST", url, true);

Siendo url, una variable que almacena la url destino.

Enviando los parámetros necesarios.

Ahora solo nos queda enviar los parámetros necesarios a la página, eso lo tenemos que realizar por medio del método send. Los parámetros, tenemos que enviarlos como un string, así que si no queremos enviar ningún parámetro, la llamada al método sería la siguiente:

request.send("");

Y si quisieramos enviar parámetros, tendríamos que hacerlo como una cadena de clave-valor concatenandolos con &, ademas y como vamos a enviar los datos vía POST, tenemos que indicarlo en la cabecera de la petición.

Sería algo así:

request.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
request.send("name=pepe&surname=perez");

Implementando el Handler que va a manejar la respuesta.

Como ya hemos hecho la petición, ahora solo nos queda implementar el handler que manejara la respuesta. En él, tendremos que preguntar por el estado del objeto, los posibles valores que nos puede devolver son:

  • 0 -> sin analizar
  • 1 – > abierto
  • 2 -> cabeceras recibidas
  • 3 -> cargando
  • 4 -> completado

Una vez que el objeto nos devuelve el valor 4 (completado), tenemos que ver si ha ido bien, esto lo haremos por medio de la propiedad status del objeto que nos va a devolver el status code (404 no encontrado, 200 ok etc.…).

La implementación sería algo así:

function callWSComplete_Handler()
{
if(request.readyState == 4)
{
if(request.status == 200)
{
alert("la respuesta es: " + request.responseXML.text);
}
else
{
alert("ha surgido un problema... :-(");
}
}
}

Y esto es todo por hoy mis drugitos, como veis, el hacer peticiones síncronas o asíncronas con el objeto XMLHttpRequest no es muy complejo y aunque sea más fácil hacerlo por medio de algún Framework, siempre es bueno saber que funciona este objeto ya que como he dicho anteriormente es en el que se basan todos los Frameworks (o todos los que yo conozco) para trabajar con Ajax.

Peticiones Síncronas.

Como aclaración, si realizamos una petición asíncrona, el código del script se seguirá ejecutando y una vez se reciba la respuesta el evento se manejara por medio de la función que hayamos indicado en la propiedad onreadystatechange. Si prefieres realizar peticiones síncronas, el script esperara a que se reciba la respuesta para continuar y no tendrás que implementar ningún handler para manejar el evento (ni tampoco indicárselo al objeto por medio de la propiedad onreadystatechange).

Descargas – Download.

Mientras he escrito este post he estado escuchando a los ya desaparecidos Humbert Humbert. Siempre grandes.

Anuncio publicitario

3 pensamientos en “Llamando a Web Services por medio del objeto XMLHttpRequest de Javascript.

  1. Estoy usando el ejemplo que tienes pero al cambiar la url del web service y mandarlo llamar me manda un error en la instrucción:

    request.open(«POST», url, true );

    El error es:

    Microsoft JScript runtime error: Permission denied

    ya agregue al web.config lo siguiente:

    para no tener problemas al usar web services remotos pero aun asi me manda el problema.

    • Ya supe cual era el problema, solo hay que modificar la configuración de seguridad del IE de la siguiente forma:

      1 .- Dentro de IE8 sigues la ruta: Herramientas>Opciones De Internet>Seguridad>Nivel Personalizado…

      2 .- Buscas la opción TENER ACCESO A ORIGEN DE DATOS ENTRE DOMINIOS (en mi caso se encuentra como antepenúltima opción) y la habilitas.

      3 .- Clic en ACEPTAR

      4 .- Clic en APLICAR y después en ACEPTAR

      Christian Arroyo

  2. Christian, podrias pasarme el código que debe ir en el web.config para acceso remoto. Por favor. Yo sigo teneindo el mismo problema y no lo he resuelto.

    Juan Manuel Alegría B.

Deja una respuesta

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s