Ver índice
Empezando con Ajax

        Ocultar índice  

   Índice de contenidos
   Instalación en Windows
   Instalación en Ubuntu
   Servidores seguros
   Páginas dinámicas
   Sintaxis básica
   Operaciones
   Arrays
   Formatos de presentación
   Operadores
   Bucles
   Extraer y ord. información
   Funciones
   Ficheros externos
   Imágenes dinámicas
   Gestión de directorios
   Cookies y sesiones
   Clases y objetos
   Ficheros en formato PDF
   Bases de datos MySQL
   PHP y XML
   PDO - Bases SQLite / MySQL
   MySQL a traves de misqli
   Algo de JavaScript y AJAX


AJAX (Asynchronous JavaScript and XML)

Modificaciones parciales en una web

Sin meternos en grandes profundidades del JavaScript ni del llamado DOM (Document Object Model) lo conocido como AJAX (Asynchronous JavaScript and XML) no es un lenguaje de programación ni tan siquiera una herramienta. Es simplemente la combinación de otras tecnologías ya existentes entre las que cabe destacar: HTML y CSS, DOM y JavaScript, el objeto XMLHttpRequest y, también, XML. El uso conjunto de estas tecnología nos va a permitir intercambiar datos con el servidor y actualizar partes de una página web sin necesidad de recargar totalmente la página.

Un elemento imprescindible para estos propósitos es la interface conocida como XMLHttpRequest que, aunque desarrollada inicialmente por Microsoft, en la actualidad está integrada prácticamente todo los navegadores como un clase Javascript cuyos objetos se encargan, desde el propio navegador y a través de sus propios métodos, de realizar la comunicación bidireccional con el servidor.

Crear objetos JavaScript

Dado que XMLHttpRequest es un objeto JavaScript empezaremos por comentar la sintaxis de creación de objetos en este lenguaje que no difiere prácticamente en nada de la ya comentada cuando los creábamos en PHP. Igual que ocurría allí, mediante la sintaxis

objeto = new XMLHttpRequest()

incluida entre dos etiquetas <script type="text/javascript"></script> estaríamos creando un objeto de la clase XMLHttpRequest. Este será el elemento básico para el uso de AJAX y funcionará con las versiones más actuales de los navegadores habituales.

Por «no romper con las tradiciones», es posible que puedas encontrarte con algunos navegadores antiguos que no incluyen esta interface y que, en el caso de Internet Explorer, van a requerir el uso de una sintaxis alternativa tal como puedes ver en este ejemplo de código fuente.

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<title>Objeto Ajax</title>
<script type="text/javascript">
        if(window.XMLHttpRequest) {
            objetoAjax = new XMLHttpRequest();
        }
            else if(window.ActiveXObject) {
		    objetoAjax = new ActiveXObject("Microsoft.XMLHTTP");
        }

        alert(objetoAjax);

</script>
</head>
<body>
</body>
</html>
Ver ejemplo

Propiedades del los objetos XMLHttpRequest

Es importante tener bien que la secuencia de utilización práctica de los objetos XMLHttpRequest que es la siguiente:

Igual que ocurría en PHP y tal como comentamos en la página anterior los objetos JavaScript tiene propiedades a las que se alude mediante la sintaxis nombre_del_objeto.nombre_de_la_propiedad. En el caso de los objetos de la clase XMLHttpRequest las propiedades más importantes son las relativas a los pasos enemurados anteriormente y que en resumen son las siguientes:

Métodos del los objetos XMLHttpRequest

Igual que ocurría en PHP y tal como comentamos en la página anterior los objetos JavaScript disponen de métodos a los que se alude con la sintaxis nombre_del_objeto.nombre_del_metodo(parametros). En el caso de los objetos de la clase XMLHttpRequest las métodos más usuales son los siguientes:

El «gran hermano» de XMLHttpRequest

Además de los métodos y propiedades antes aludidos un elemento imprescindible para su correcta utilización. Se trata del evento:

En este ejemplo puedes ver (los resultados varían dependiendo del navegador que estés usando) la lista de propiedades de un objeto XMLHttpRequest. La visualización utiliza un bucle Javascript con la siguiente sintaxis:

for (var=variable in nombre_del_objero){    //recorre el objeto pasando por cada una de sus propiedades
document.write(variable+"<br>"); //escribimos el nombre de la propiedad concatenado con un salto de linea
}
Ver ejemplo Ver código fuente

Lectura de datos de un fichero de texto

Empezaremos con un ejemplo muy sencillo. Se trata de utilizar el objeto XMLHttpRequest para acceder al servidor, leer el contenido de un fichero de texto e incluir su contenido en una div de la página actual. El proceso es el siguiente:

La forma de creación del objeto XMLHttpRequest ha sido descrita más arriba. El resto del proceso podría incluirse en una función como esta:

/* la función recibe dos parámetros, la URL de la página que va a solicitarse
   al servidor (origen) y la div en la que van a escribirse los resultados */
function obtenerDatos(origen, dest){
    /* comprueba que existe el objeto XMLHttpRequest */
    if(objetoAjax) {
        /*recogemos el valor dest en la variable GLOBAL destino
          su condición de global se debe a que no lleva delante la
          palabra reservada var. De esta forma (GLOBAL) destino estará disponible
          para cualquier funcion o parte del script */
        destino=dest;
        /*preparamos la petición mediante el open. Incluimos el parámetro GET y el
          la dirección de la URL que solicitaremos al servidor. No incluimos el parámetro tipo
          con lo cual tomará su valor por defecto que es true. */
        objetoAjax.open("GET", origen);
        /* asignamos al evento cambio de estado la ejecucion de la funcion
           gran_hermano. Observa que no ponemos paréntesis en la llamada. Elo se debe a que
           lo que pretendemos es asignar al evento la ejecucion de la función. Si incluyéramos
           los paréntesis tipicos gran_hermano() lo que estaríamos tratando de asignar al evento
           no sería la ejecución de la función sino el resultado de esta. */
        objetoAjax.onreadystatechange  = gran_hermano;
        /* preparada la peticion y activada la captura de eventos ya solo nos queda
           enviar la peticion al servidor */
        objetoAjax.send(null);
    } //cerramos el if
} //finalizamos la funcion

/* esta funcion no recibe ningun parámetro pero tiene disponible el valor de
   la variable destino creada (creada como GLOBAL) por la función anterior */

function gran_hermano(){
    /* comprueba si la propiedad readyState vale 4 (Transaccion completada)
       y que la petición haya sido considerada correcta por el servidor (status=200)*/
    if (objetoAjax.readyState==4 && objetoAjax.status==200) {
     /* si se completo correctamente la transacción escribe en la div de destino
        el texto recibido del servidor (responseText) */
        document.getElementById(destino).innerHTML = objetoAjax.responseText;
    }else{
     /* si no se completó la peticion le indicamos que escriba "procesando " */
        document.getElementById(destino).innerHTML ="procesando..";
    }
}

Aquí tienes dos casos de utilización de esa función. Observa las diferencias de respuesta.

Ver ejemplo Ver código fuente Ver ejemplo Ver código fuente

Habrás podido observar que el segundo ejemplo presenta incorrectamente algunos carácteres. La explicación es simple. En el primer caso al crear el fichero de texto lo hemos guardado con codificación UTF8 que es la que lee correctamente. El segundo fichero, idéntico al anterior, ha sido guardado con codificación ANSI y ese el origen de los problemas de visualización de los carácteres con tilde, las eñes, etcétera.

Existen otras soluciones alternativas a descrita anteriormente. En vez de la función gran_hermano incluimos una función anónima tal como puedes ver en este código fuente.

/* la función recibe dos parámetros, la URL de la página que va a solicitarse
   al servidor (origen) y la div en la que van a escribirse los resultados */
function obtenerDatos(origen, dest){
    /* comprueba que existe el objeto XMLHttpRequest */
    if(objetoAjax) {
        /*recogemos el valor dest en la variable GLOBAL destino
          su condición de global se debe a que no lleva delante la
          palabra reservada var. De esta forma (GLOBAL) destino estará disponible
          para cualquier funcion o parte del script */
        destino=dest;
        /*preparamos la petición mediante el open. Incluimos el parámetro GET y el
          la dirección de la URL que solicitaremos al servidor. No incluimos el parámetro tipo
          con lo cual tomará su valor por defecto que es true. */
        objetoAjax.open("GET", origen);
        /* asignamos al evento cambio de estado la ejecucion de la funcion
           anómina que definimos con la palabra function()  ahora con paréntesis
           ya que esa es exigencia para su definición*/
        objetoAjax.onreadystatechange  = function(){
         /* comprueba si la propiedad readyState vale 4 (Transaccion completada)
        y que la petición haya sido considerada correcta por el servidor (status=200)*/
            if (objetoAjax.readyState==4 && objetoAjax.status==200) {
            /* si se completo correctamente la transacción escribe en la div de destino
            el texto recibido del servidor (responseText) */
                document.getElementById(dest).innerHTML = objetoAjax.responseText;
            }else{
            /* si no se completó la peticion le indicamos que escriba "procesando " */
                document.getElementById(dest).innerHTML ="procesando..";
            }
        }
        /* preparada la peticion y activada la captura de eventos ya solo nos queda
           enviar la peticion al servidor */
        objetoAjax.send(null);
    } //cerramos el if
} //finalizamos la funcion


Estos son los resultados utilizando esta nueva sintaxis

Ver ejemplo Ver código fuente Ver ejemplo Ver código fuente

Una petición que envía datos y recoge resultados

  ¡Cuidado!  

Observa las diferencias entre los resultados de ambos ejemplos. Cuando se usa GET la correcta visualización de los resultados en el script php (en este caso multiplica.php) requeriría tratar la cadena de texto por medio de la función PHP utf8_decode.
No olvides que esta función, junto con utf8_encode pueden resultar muy útiles en muchas ocasiones.

Aplicación de AJAX al autocompletado de formularios

Cada día es más frecuente encontrarnos con páginas en las que los datos a incluir dentro de un campo de un formulario se nos van autosugiriendo a medida que vamos escribiendo caracteres en ese campo. A lo largo de los párrafos siguientes intentaremos ir creando, paso a paso, uno de esos formularios.

Ver ejemplo Ver código fuente