Hace unos meses atrás (mas de medio año ya...) tuve que aprender a manejarme con AJAX por la fuerza, y en una semana tuve que saber usar el objeto XMLHttpRequest (oXHR de ahora en mas). En su momento lo use para realizar una web dinámica, una agenda en PHP que usaba una base de datos MySQL. Pero el tiempo paso y cuando quise retomar me di cuenta que no solo no me acordaba, sino que no entendía como usar el bendito oXHR. Así que me pase 2 días enteros volviendo a analizar el funcionamiento de la agenda y leyendo manuales sobre AJAX para volver a encontrar el hilo de ejecución de un oXHR. Lo que he notado es que en muchas webs esta explicado demasiado técnicamente, sus métodos, atributos y algún ejemplo. Pero no hacen hincapié en la secuencia en que todo ocurre y eso es lo que yo voy a hacer acá, así que no esperen un detalle técnico de sus métodos y atributos que para eso hay cientos de copy-paste repartidos en la web.
Eso si... vamos a partir del ejemplo brindado por el libro "Introducción a AJAX" de LibrosWeb.es.
El código completo del ejemplo:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Hola Mundo con AJAX, version 2</title>
<script type="text/javascript" language="javascript">
var READY_STATE_UNINITIALIZED=0;
var READY_STATE_LOADING=1;
var READY_STATE_LOADED=2;
var READY_STATE_INTERACTIVE=3;
var READY_STATE_COMPLETE=4;
var peticion_http;
function cargaContenido(url, metodo, funcion)
{
peticion_http = inicializa_xhr();
if(peticion_http)
{
peticion_http.onreadystatechange = funcion;
peticion_http.open(metodo, url, true);
peticion_http.send(null);
}
}
function inicializa_xhr()
{
if(window.XMLHttpRequest)
{
return new XMLHttpRequest();
}
else if(window.ActiveXObject)
{
return new ActiveXObject("Microsoft.XMLHTTP");
}
}
function muestraContenido()
{
if(peticion_http.readyState == READY_STATE_COMPLETE)
{
if(peticion_http.status == 200)
{
alert(peticion_http.responseText);
}
}
}
function descargaArchivo()
{
cargaContenido("http://localhost/holamundo.txt", "GET", muestraContenido);
}
window.onload = descargaArchivo;
</script>
</head>
<body></body>
</html>
Analicemos pues entonces el ejemplo... pero por el principio:
1º Al cargarse la página lo primero que se ejecuta es código del script. Pero no todo como ya sabemos. Primero quedan definidas e inicializadas las variables (que usaremos de constantes) de los estados de la respuesta del servidor. Y luego ejecuta la funcion window.onload = descargaArchivo;.
2º En este momento (durante la carga de la pagina todavía), se hace una llamada por el evento "onload" a la funcion "descargaArchivo()", la cual llama a su vez a la funcion cargaContenido("http://localhost/holamundo.txt", "GET", muestraContenido); y aquí es donde se complica todo. Los tres parámetros en la mayoría de los manuales son explicados de forma muy técnica y no termina uno de entender como es el tema hasta que uno mismo no prueba en tiempo real la "aplicación web" y le mete los mil y un alerts para seguirle la onda. El tema es así:
- El primer parámetro es la URL del archivo que estamos solicitando de manera directa o indirecta. De ahí viene lo de Request en el oXHR, request es petición o solicitud. Y ahora explico lo de "solicitando de manera directa o indirecta", en el caso del ejemplo podemos observar que el archivo solicitado es un "holamundo.txt". Eso quiere decir que el oXHR va a indicarle al servidor que queremos que "abra" ese archivo y devuelva su contenido.
- El segundo parámetro es el metodo de envío de parámetros que puede ser POST o GET. En nuestro ejemplo da igual hacerlo por POST o por GET, ya que la URL es un archivo de texto y no otra pagina PHP que necesita que le envíen parámetros. Si todavía no se entiende la idea, recuerden esto, que mas adelante se aclara.
- El ultimo parámetro es el nombre de la funcion que queremos que se ejecute cuando el servidor cambie de estado al estado "READY_STATE_COMPLETE". Así que cumple dos tareas, por un lado asegurarse de que en cada cambio de estado del servidor compruebe si llego al estado de petición completada y si es así que recupere la información que nos envía el servidor, esto también si no se termina de entender aquí lo explicare mas adelante.
En este momento deberíamos tener mas claro el asunto, solo queda ultimar detalles y explicar otros usos.
3º La funcion "cargaContenido(...)" va realizar 5 tareas.
- Va a inicializar el oXHR.
- Va a comprobar que fue correctamente inicializado el oXHR.
- Si el objeto fue correctamente inicializado definirá que funcion es la que se ejecuta cada vez que el servidor cambia de estado. Recuerdan el ultimo parámetro? aquí es donde es aplicado. Por medio del metodo onreadystatechange, cada vez que el server cambia de estado durante la petición, la funcion definida aquí es ejecutada, en nuestro caso "muestraContenido()" que como ya había dicho cumple dos tareas... léanlo de nuevo seguro que ahora les queda mas claro. Pero todavía no ejecuta nada.
- Establece los parámetros de la petición, así que básicamente no ejecuta nada todavía.
- Finalmente se envía la petición al servidor y comienza la verdadera ejecución. Cuando el servidor cambie de estado se invocara a "muestraContenido()" tantas veces como sea necesario hasta que la petición sea completada, momento en que el atributo "readyState" va a indicar que la petición fue completada. Luego verificamos el estado devuelto por el servidor (que no es el estado de la petición) y si esta todo OK, entonces la respuesta será almacenada en "responseText".
- Solo queda usar el contenido de "responseText" para lo que necesitemos, en el ejemplo simplemente mostramos una alerta cuyo texto es el contenido del archivo "holamundo.txt".
Con esto todas las fichas terminan de caer y ahora podemos hacer algunas acotaciones extras. Si por ejemplo, en lugar de un archivo "holamundo.txt" tenemos un "holamundo.php" cuyo contenido es simplemente:
<?echo "Hola mundo";?>
El servidor NO ABRE el archivo "holamundo.php" como ocurría con el "holamundo.txt", sino que lo interpreta y devuelve el correspondiente HTML producido por ese PHP. El contenido de este archivo HTML es simplemente "Hola mundo".
Esto quiere decir que si la "URL" del metodo "open" del oXHR hace referencia a un archivo PHP, este primero será interpretado por el servidor y el atributo "responseText" contendrá el contenido del HTML devuelto por la interpretación del PHP. Lo que significa que si nuestro archivo PHP no devuelve nada "responseText" no contendrá nada, o mejor dicho será una cadena vacía. Pero no es un problema, muy por el contrario aquí es donde entra la parte del envío de datos a base de datos, verificaciones del lado del servidor, etc.
Entonces por ejemplo, supongamos el clásico formulario de datos para registrar una cuenta de mails. De esta forma podemos llamar a un archivo "GuardarDatos.php" que reciba los parámetros enviados por el metodo "send" del oXHR usando el metodo "POST", los verifique, si están mal "responseText" devolver la cadena "fail" y nuestro javascript de la pagina del formulario donde cargamos los datos y le dimos guardar, reaccionara y nos indicara que los datos no fueron correctamente llenados (en realidad esto es incorrecto, pues este tipo de validación deberíamos hacerlo del lado del cliente, del lado del servidor se hacen las validaciones en el momento del login, pero es para no explicar también el proceso del login). Pero si están bien, se guardaran en la base de datos, y el "responseText" devolverá un "ok", a lo cual nuestro javascript reaccionara simplemente enviándonos a la pagina de login.
Otra situación que podemos tener es que necesitemos consultar la base de datos y obtener una lista de los registros y mostrarlos en una tabla (de mas esta decir que seguramente necesitaremos que la tabla sea construida dinámicamente), para lo cual el string de "responseText" nos puede resultar inadecuado. aquí es donde entra el atributo "responseXML". Al construir el HTML por medio del PHP a este HTML le podemos dar el formato no de un HTML, sino de un XML, y ordenar los datos requeridos de la base de datos en este XML. Usando "responseXML" podremos acceder al XML como tal (y no como texto), con lo cual podremos actuar sobre el usando DOM, tanto para leer el XML como para construir la tabla dinámica.
En otras palabras, el oXHR nos permite ejecutar código PHP (en el servidor... obvio) sin recargar una pagina, y por medio de javascript según lo que obtengamos del servidor, modificar la pagina actual.
Y creo que eso es todo, espero que el tema les haya quedado mas claro (y aclaro que es también para mí, cuando en un futuro no me acuerde como funcionaba esto jejeje). Es posible que me haya saltado alguna que otra cosa, esto lo escribí algo rápido, cualquier cosa, me consultan y le aplicare las modificaciones pertinentes, llegado el caso. Saludos.
Leer toda la nota...