miércoles, 28 de enero de 2009

Combinando Ajax con PHP, Parte 1


En los ejemplos anteriores observamos como se puede solicitar un recurso a nuestro servidor Web para desplegar su información en la pantalla, además de archivos de texto simple o XML también podríamos haber solicitado una página HTML, pero la limitación de este proceso es que solo desplegamos información estática, si queremos que los recursos a los que accedamos puedan devolvernos una respuesta dinámica, es necesario contar con una aplicación del lado del servidor que permita arrojar resultados distintos, en las diferentes peticiones que se realicen. Una de las formas de lograrlo es accediendo a un servicio web o a una aplicación web, que pueden ser desarrolladas en distintos lenguajes de programación. En este ejemplo veremos como acceder a una pequeña aplicación web programada en PHP, y para hacerlo un poco más interactivo probaremos además enviar datos a esta aplicación, como parte de los parámetros de nuestra petición.

Principios a tener en cuenta:
  • En este caso tendremos que llevar a cabo dos programaciones, una en Javascript+Ajax en la página HTML desde la que realizaremos nuestra petición, que estará en nuestro cliente o navagador de Internet, y otra del lado del servidor que consistirá en la aplicación PHP.
  • Del lado del cliente los datos se enviarán como parte de la petición al servidor. Hay que tomar en cuenta que en una petición "el objeto XMLHttpRequest puede enviar parámetros tanto con el método GET como con el método POST de HTTP. En ambos casos, los parámetros se envían como una serie de pares clave/valor concatenados por símbolos &. El siguiente ejemplo muestra una URL que envía parámetros al servidor mediante el método GET:
    http://localhost/aplicacion?parametro1=valor1&parametro2=valor2
  • La principal diferencia entre ambos métodos es que mediante el método POST los parámetros se envían en el cuerpo de la petición y mediante el método GET los parámetros se concatenan a la URL accedida. El método GET se utiliza cuando se accede a un recurso que depende de la información proporcionada por el usuario. El método POST se utiliza en operaciones que crean, borran o actualizan información."[1]
  • Del lado del servidor se tendrá un archivo llamado validaDatos.php, en el que se obtendrán los datos por medio de las variables predefinidas de PHP, y dependiendo del tipo de dato recibido se generará una respuesta de salida como parte del contenido de una página HTML.
Programación del lado del cliente:

Los datos que enviaremos como parte de la petición se tomaran de un formulario HTML, y se incluirán en una cadena de texto estructurada, que se enviará como parte de la petición al servidor web, esta cadena recibe el nombre de consulta (query).

El código HTML para este formulario aparece a continuación, dentro de éste no se incluye el código Javascript para llevar a cabo la petición con Ajax, pero se indica el lugar en el que se deberá colocar posteriormente, esto se hace así para explicar con más calma el ejemplo:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Tercer ejemplo con Ajax, combinándolo con PHP</title>
<script language="javascript">
<!--Sitio del código Javacript-->
</script>
</head>
<body>
<form>
<label for="txtAutor">Autor:</label>
<input type="text" id="txtAutor" name="txtAutor" size="40" /><br/>
<label for="txtAnio">Año:</label>
<input type="text" id="txtAnio" name="txtAnio" size="10" /><br/>
<label for="txtTitulo">Títiulo:</label>
<input type="text" id="txtTitulo" name="txtTitulo" size="50" /><br/>
<input type="button" value="Validar datos" onclick="valida()" />
</form>
<div id="divRespuesta"></div>
</body>
</html>


En ésta ocasión utilizaremos el conjunto de caracteres UTF-8 para la codificación de nuestros archivos, lo cual aparece señalado por el campo chaset en el encabezado de la página HTML. Como podemos ver el formulario consiste en tres cuadros de texto señalados con etiquetas y un botón a través del cual se iniciará el proceso, que tiene una apariencia como la siguiente:


Ahora bien, el código Javascript que utilizaremos iniciará su ejecución al hacer clic sobre el botón "Validar datos", por lo que antes de indicar éste evento en el botón deberemos incluir dentro de las etiquetas <script>...</script> el siguiente programa:


var READY_STATE_COMPLETE=4;
var peticionHttp = null;
//Función que devuelve el objeto de la clase XMLHttpRequest
function inicializaXhr() {
if(window.XMLHttpRequest) {
return new XMLHttpRequest();
}
else if(window.ActiveXObject) {
return new ActiveXObject("Microsoft.XMLHTTP");
}
}
//Función que crea la cadena con los parámetros de la petición POST
function creaCadenaDeDatos() {
var autor = document.getElementById("txtAutor");
var anio = document.getElementById("txtAnio");
var titulo = document.getElementById("txtTitulo");
return "txtAutor=" + encodeURIComponent(autor.value) + "&txtAnio=" + encodeURIComponent(anio.value) + "&txtTitulo=" + encodeURIComponent(titulo.value) + "&nocache=" + Math.random();
}
//Función que inicia todo el proceso y lleva a cabo la petición al servidor
function valida() {
peticionHttp = inicializaXhr();
if(peticionHttp) {
peticionHttp.onreadystatechange = procesaRespuesta;
peticionHttp.open("POST", "http://localhost/validaDatos.php", true);
peticionHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
var cadenaDeDatos = creaCadenaDeDatos();
peticionHttp.send(cadenaDeDatos);
}
}
//Función que procesa la respuesta HTML del servidor Web
function procesaRespuesta() {
if(peticionHttp.readyState == READY_STATE_COMPLETE) {
if(peticionHttp.status == 200) {
document.getElementById("divRespuesta").innerHTML = peticionHttp.responseText;
}
}
}


Dentro del código nos encontramos con una refactorización de algunos pasos, lo cual obedece a facilitar su utilización a partir de este ejemplo y los que sigan, facilitando además el mantenimiento de estos programas. En el nuevo código fuente vemos que al inicio se declaran dos variables globales:
var READY_STATE_COMPLETE=4;
var peticionHttp = null;
La variable READY_STATE_COMPLETE se utiliza como una constante, que servirá para comprobar que el estado de la respuesta del servidor se encuentra completa en la función procesaRespuesta que veremos más adelante, debido a que en éste ejemplo solo nos intereza el estado completo de la respuesta no declaramos los otros 4 posibles estados (no inicializada , cargando, cargada e interactiva). La segunda variable global es peticionHttp, al igual que la anterior podrá ser accedida por todas las funciones del programa, y al iniciarse el proceso -como en los ejemplos anteriores- se convertirá en el objeto a través del cual llevaremos a cabo la petición al servidor. La segunda refactorización importante consiste en la creación de la función inicializaXhr:
function inicializaXhr() {
if(window.XMLHttpRequest) {
return new XMLHttpRequest();
}
else if(window.ActiveXObject) {
return new ActiveXObject("Microsoft.XMLHTTP");
}
}
Esta función se utilizará se emplea para encapsular la creación del objeto XMLHttpRequest, incluyendo la validación de compatibilidad y devolviendo la instancia de la clase XMLHttpRequest. De modo que bastará con inicializar una variable con el resultado devuelto para tener creado nuestro objeto XMLHttpRequest.
function creaCadenaDeDatos() {
var autor = document.getElementById("txtAutor");
var anio = document.getElementById("txtAnio");
var titulo = document.getElementById("txtTitulo");
return "txtAutor="+encodeURIComponent(autor.value)+"&txtAnio="+ encodeURIComponent(anio.value)+"&txtTitulo="+encodeURIComponent(titulo.value) + "&nocache=" + Math.random();
}
La función creaCadenaDeDatos obtiene los datos del formulario, accediendo a cada uno de sus elementos por medio de sus identificadores, creando un objeto del DOM para cada uno, lo cual permite utilizar su propiedad value y obtener los valores capturados por el usuario, con el propósito de concatenarlos en una cadena. Estos valores son codificados para formar una URI válida antes de ser concatenados. Esta cadena representa los parámetros que serán enviados al servidor, contando con las parejas clave/valor separadas por el caracter ampersand "&" como habíamos mencionado en las notas iniciales. Una vez concatenada la cadena ésta es devuelta como la respuesta de la función.

La siguiente función que aparece, llamada valida, en donde se iniciará todo el proceso y se llevara a cabo la petición al servidor:
function valida() {
peticionHttp = inicializaXhr();
if(peticionHttp) {
...
Al inicio de la función valida se lleva a cabo la creación del objeto de la clase XMLHttpRequest , que será peticionHttp como ya habíamos mencionado. Después realizamos una validación para comprobar que el objeto se haya instanciado correctamente, por medio de la condición que aparece. En las siguientes dos líneas:
peticionHttp.onreadystatechange = procesaRespuesta;
peticionHttp.open("POST", "http://localhost/validaDatos.php", true);
Indicamos que cuando el servidor regrese la respuesta a la petición se ejecute la función procesaRespuesta. En la segunda línea indicamos que el tipo de petición será POST, que la dirección URL del recurso solicitado es "http://localhost/validaDatos.php" y que la petición será asíncrona. La clave del envio de datos al servidor se encuentra en las siguientes tres líneas:
peticionHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
var cadenaDeDatos = creaCadenaDeDatos();
peticionHttp.send(cadenaDeDatos);

El método setRequestHeader en este caso establece que se enviará un encabezado como parte de la petición que incluye un Content-Type de tipo application/x-www-form-urlencoded, es decir que le indica al servidor que los datos que se están enviando en la petición son del tipo indicado por éste segundo parámetro. De no indicarse el tipo de contenido por medio de este método o al hacerlo de manera incorrecta, el servidor descartará todos los datos que sean enviados dentro de la petición HTTP. Así, para enviar parámetros mediante el método POST, es obligatorio incluir el encabezado Content-Type mediante éste método.

Los parámestros que serán enviados se obtienen por medio del método creaCadenaDeDatos y se almacenan en cadenaDeDatos, el método send recibe ésta cadena envía su contenido como parámetros al servidor.

La función procesaRespuesta se encargará de desplegar la información devuelta por la página PHP y es similiar a las que ya habiamos utilizado para este propósito, añadiendose la variable READY_STATE_COMPLETE para comprobar el estado de la respuesta.
document.getElementById("divRespuesta").innerHTML = peticionHttp.responseText;
Solo que en este caso todo la información será desplegada dentro del elemento "divRespuesta" de la página HTML.

Una vez que agregamos éste código Javascript a nuestro archivo HTML bastará con incluir en el botón "Validar datos" la llamada a la función valida() en su evento onclick, es decir:
<input type="button" value="Validar datos" onclick="valida()" />
para tener finalizada la programación del lado del cliente en este ejemplo.

Ahora solo necesitamos implementar el progrmaa PHP que contedrá el archivo validarDatos.php que se alojará en nuestro servidor Web, pero ese será el contenido de la segunda parte de este tema, que veremos en el siguiente post.

Hasta la próxima.

Referencias.
[1]Introducción a Ajax. Javier Equíluz Pérez. Junio de 2008.


0 comentarios:

Publicar un comentario