Mini-tutorial de AJAX

Sofá Naranja, en su empeño por acercar la tecnología al pueblo, presenta un mini-tutorial sobre el palabro de moda: AJAX. Si andabas buscando una excusa para trastear con AJAX, la acabas de encontrar. AJAX es fácil. AJAX es potente. AJAX lava más blanco. AJAX es, en definitiva, una Cosa Guapa™

¿Qué es AJAX?

AJAX son las siglas de Asynchronous JavaScript And XML. Es una colección de tecnologías que permiten desarrollar webs altamente interactivas ahorrando ancho de banda y recargas de página.

La clave para el funcionamiento de AJAX es el objeto XMLHttpRequest (uno de los pocos inventos útiles de Microsoft, mira por dónde)

Actualmente, AJAX funciona en los siguientes navegadores:

  • Mozilla y familia
  • Internet Explorer Windows (a partir de la versión 5)
  • Safari y familia (en teoría, no tengo un Konqueror para probar)

Más información en la Wikipedia

Qué necesitamos para este tutorial

  • Un editor de texto
  • Un servidor web
  • Café (opcional)
  • Unos 30 minutillos

Vamos a construir una página web simple, donde cargaremos datos a partir de otra sin necesidad de recargar la página actual. También veremos como darle al usuario un poco de “feedback” de qué está pasando. Con suerte, también nos tomaremos un café.

Empezamos

La cosa empieza suave. Vamos a crear un fichero HTML (que en un derroche de originalidad llamaremos ‘index.html’) con el siguiente contenido (véase que somos unos pedantes y vamos a usar sintaxis XHTML 1.1 pata negra):

index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es">
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <title>Mini-tutorial AJAX</title>
    </head>
    <body>
        <h4>Mini-tutorial AJAX</h4>
        <div id="detalles"></div>
    </body>
</html>

Como vemos, nada del otro mundo. Nótese el detalle de que tenemos un DIV vacío, al que le hemos asignado un ID único. Es en este DIV donde vamos a cargar nuestro contenido dinámico.

Complicando el tema

Ahora vamos a crear el objeto XMLHttpRequest, que será el encargado de actualizar el contenido dinámico de nuestro DIV ‘detalles’.

Creamos un fichero (que, recurriendo a nuestra creatividad habitual, llamaremos ‘ajax.js’):

ajax.js

//  Vamos a presuponer que el usuario es una persona inteligente...
var isIE = false;
//  Creamos una variable para el objeto XMLHttpRequest
var req;
//  Creamos una funcion para cargar los datos en nuestro objeto.
//  Logicamente, antes tenemos que crear el objeto.
//  Vease que la sintaxis varia dependiendo de si usamos un navegador decente
//  o Internet Explorer
function cargaXML(url) {
    //  Primero vamos a ver si la URL es una URL :)
    if(url==''){
        return;
    }
    //  Usuario inteligente...
    if (window.XMLHttpRequest) {
        req = new XMLHttpRequest();
        req.onreadystatechange = processReqChange;
        req.open("GET", url, true);
        req.send(null);
    //  ...y usuario de Internet Explorer Windows
    } else if (window.ActiveXObject) {
        isIE = true;
        req = new ActiveXObject("Microsoft.XMLHTTP");
        if (req) {
            req.onreadystatechange = processReqChange;
            req.open("GET", url, true);
            req.send();
        }
    }
}

Bien. De momento tenemos una función que crea un objeto XMLHttpRequest (con una u otra sintaxis, dependiendo del navegador) y le asigna la función ‘processReqChange’ al evento ‘onreadystatechange’ (que ahora explicaremos qué quiere decir :)

También hemos usado el método ‘open’ de XMLHttpRequest (que se usa para asignarle la dirección URL de donde va a cargar los datos) y el método ‘send’ (que se usa para efectuar la llamada a la URL asignada con ‘open’)

Nos vamos a detener un poco en la sintaxis de ‘open’:

open('metodo','URL',modo-asincrono,'usuario','password');

Los dos primeros parámetros son obligatorios. ‘metodo’ puede ser GET o POST, modo-asincrono es un booleano (TRUE|FALSE) que indica si la llamada será asíncrona (se seguiran ejecutando scripts en la página mientras se cargan los datos) o no (se detendrá la ejecución de los scripts hasta que se complete la carga de datos). ‘usuario’ y ‘password’ son, sorprendentemente, el usuario y el password a usar si la URL requiere autentificación

Seguimos…

Ahora declararemos la función processReqChange:

function processReqChange(){
    //    Referencia a nuestro DIV con ID unica:
    var detalles = document.getElementById("detalles");
    //    Si se ha completado la carga de datos, los mostramos en el DIV...
    if(req.readyState == 4){
        detalles.innerHTML = req.responseText;
    } else {
        //    ...en caso contrario, le diremos al usuario que los estamos cargando:
        detalles.innerHTML = '<img src="loading.gif" align="absmiddle" /> Cargando...';
    }
}

processReqChange es una función que se ejecuta cada vez que se dispara el evento ‘onreadystatechange’ del objeto XMLHttpRequest. ¿Y cuando se dispara este evento? Pues, como su propio nombre indica, cada vez que cambia el estado del objeto. Este evento le asigna al objeto XMLHttpRequest una variable (‘readyState’) que puede tener los siguientes valores (puede tener más, pero es que si no esto no sería un mini-tutorial):

  • 0 = no inicilizado (por ejemplo, cuando acabamos de crear el objeto)
  • 1 = cargando datos (hemos llamado al método ‘send’ del objeto)
  • 4 = carga completada (ya podemos acceder a los datos que nos ha devuelto el servidor)

Entonces, cada vez que cambie la variable ‘readyState’ miramos si es igual a 4 (carga completada), y si es así metemos el contenido del objeto XMLHttpRequest

req.responseText

en nuestro DIV

detalles.innerHTML = req.responseText

Integrando el script

Ahora vamos a enlazar el JavaScript con el HTML (por aquello de que funcione, y tal… es que si no no tiene gracia…)

index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es">
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <title>Mini-tutorial AJAX</title>
        <script src="ajax.js" language="JavaScript"></script>
    </head>
    <body>
        <h4>Mini-tutorial AJAX</h4>
        <div id="detalles"></div>
    </body>
</html>

Bien… ahora nos falta llamar a la función ‘cargaXML’ de alguna forma. En nuestro ejemplo, vamos a usar un ‘select’ más o menos de este pelaje:

<select onchange="cargaXML(this.value)">
    <option value="">Elige...</option>
    <option value="001.html">001</option>
    <option value="002.html">002</option>
    <option value="003.html">003</option>
</select>

Lo que estamos haciendo es decirle al navegador que cuando cambie la selección (‘onchange’) se ejecute la función ‘cargaXML’ con la URL que hemos puesto en el ‘value’ como parámetro’.

Nuestro ‘index.html’ definitivo quedaría tal que así (voy a añadir unos estilos para que se vea más claramente nuestro DIV ‘detalles’, y para que veamos que se puede decorar el contenido cargado dinámicamente con CSS):

index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es">
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <title>Mini-tutorial AJAX</title>
        <script src="ajax.js" language="JavaScript"></script>
        <style>
            #detalles {
                margin: 20px;
                border: 1px solid #F0F0F0;
                padding: 10px;
                font-size: 10px;
            }
        </style>
    </head>
    <body>
        <h4>Mini-tutorial AJAX</h4>
        <select onchange="cargaXML(this.value)">
            <option value="">Elige...</option>
            <option value="001.html">001</option>
            <option value="002.html">002</option>
            <option value="003.html">003</option>
        </select>
        <div id="detalles"></div>
    </body>
</html>

Lógicamente, ahora deberemos crear los ficheros ’001.html’, ’002.html’ y ’003.html’. Esto, como diría mi profesor de álgebra, es trivial y se deja como ejercicio para casa.

Nota: si estás pensando en usar una URL externa a tu dominio, que se te vaya quitando la idea de la cabeza. XMLHttpRequest está sometido a las mismas restricciones de seguridad que el sandbox de JavaScript: no puedes usar el protocolo file:// y no puedes acceder a direcciones fuera de tu dominio. Ahora bien, si tu proveedor es un poco freestyle en temas de seguridad (y es un tema que, digamos, tampoco te preocupa demasiado a ti) puedes usar el viejo truco de incluir el fichero mediante PHP:

include('url-externa-de-la-que-no-sabemos-nada');

Vaya por delante que hacer esto es una locura, y que lo más probable es que tu proveedor no te deje ni intentarlo.

Chapando

Bueno, pues de momento esto es todo… aquí os dejo un ZIP con todos los ficheros, y espero vuestros comentarios.

Para más información, y un tutorial más completo sobre XMLHttpRequest (incluyendo algunas nociones de cómo parsear XML) date una vuelta por la web de Apple Developer

74 thoughts on “Mini-tutorial de AJAX”

  1. Hola, el tutorial es bien sencillo me sirvio porque estoy hace poco comenzando a informarme sobre ajax y esto me sirve para tener algo mas que solo documentos que explican de que trata esto, me refiero a codigo. Espero que puedan seguir con los tutoriales de ajax. Saludos!

    pd: proximos tutoriales o manuales serán muy bien recibidos :)

  2. Muy bien! felicitaciones al creador de este minitutorial, para principiantes es muy bueno ya que da la idea a grandes rasgos de lo que se puede hacer con AJAX de una manera rápida y simple.

  3. Exelente tutorial, pero tengo una duda, como hago para que al cargar la pagina index, el div contenedor ya tenga una pagina en carga, osea cargue la una pagina principal sin necesidad de pinchar el enlace. Se entiende?…

  4. Para que al cargar el index ya aparezca una página en el div contenedor, tendrías que cambiar el tag <body> por algo como <body onload=”cargaXML(’001.html’)”>

  5. Una pregunta:

    a ti te funciona detalles.innerHTML = req.responseText con internet explorer? a mi no…

  6. No sé si queda claro en el tutorial, pero lo ideal es desarrollar usando un servidor web. Si abres los ficheros desde local, IE aplica una serie de restricciones de seguridad que pueden hacer que falle lo de

    etalles.innerHTML = req.responseText
    .

    En las últimas versiones de IE aparece un mensaje de error que te pregunta si quieres ejecutar “contenido activo”, y si no le dices que sí no funciona el ejemplo.

    Las pruebas las he hecho con IE 6.0.2900 (el que viene con el SP2)

  7. Excelente tutorial !!! pero tengo una duda: ¿como puedo hacer para que la funcion cargaXML() reciba como parametro el nombre de otro div en el que cargar la información?

    Estuve tratando de modificar el codigo y me arroja un error asi que agradecería un ejemplo de como hacer esto.

    Felicitaciones nuevamente!

  8. Gran ayuda bro esto si es util espero puedas publicar mas ejemplos

  9. Muy buen sitio:

    Tengo una pregunta, existe algun tutorial de AJAX que permita conectar el objeto para que se alimente desde una BD en MYSQL o en PostGress??

    Gracias y felicitaciones

  10. Gracias por el tutorial, ahora tengo una idea de lo que puedo ahace con ajax, me gustaria que pongas uno que se incruste en el php (no como html en php), y que saber si hay alguna manera de pasarles parametros a una funcion que seleccione el div al que se carga la pagina

  11. Hombreeeeeeee! de lujo este tutorial. Bastante efectivo.

    Me acabas de abrir la puerta que estaba cerrada con todo ese asunto del AJAX. En verdad, gracias por compartir este conocimiento.

    Uyyy, es muy potente y eficaz tu codigo, ya lo probe inclusive con acceso a bases de datos (php/mysql) y jala excelentemente bien!

  12. Hola muy bueno este tutorial y felicidades al creador, pero tengo una unda duda al respecto:

    yo tengo una pagina en php que va mostrando registros una ves que estos son publicados, pero hay que hacer manual la actualizacion de la pagina, como yo pudiera mostrar los nuevos registros que entran con ajax y sin tener que recargar la pagina completa solo el div donde muestro los titulares.

    Espero puedan ayudarme, saludos rromero@jrebelde.cip.cu

  13. Buen tutorial ^^, gracias por dar este material, ahora tengo las cosas mas claras para terminar mi formulario …….q sigan los tutos xD!!!

  14. Muy bueno el tutorial..

    Ahora una consultilla, como puedo pasar texto de un area de texto para visualizarlo en la misma página, algo asi como un editor en que abajo se ingresa el texto html y arriba de visualiza…. Gracias.

  15. Si pones a la función processReqChange; parentesis al llamarla: processReqChange(); ¿porque no va? es quería añadirle un parametro para decirle la etiqueta del div donde cargar

  16. koby, si le pones paréntesis no funciona porque entonces lo que estás haciendo es asignarle a onreadystatechange lo que sea que devuelva la función processReqChange.

    Si quieres asignar un div, lo mejor es que lo pases como parámetro a cargaXML cuando haces la llamada AJAX… (esto me recuerda que tengo que actualizar el código con unas mejoras que tengo por ahí guardadas…)

  17. porqué no puedo guardar los valores que me devuelve la función en el “responseText” en una variable global para utilizarla desde otra función? parece que las destruye y me salen como “undefined”

  18. Buenas, el tutorial está de lujo, pero yo soy un poco cenutrio y apenas se me ocurre variar algo. Lo encontré mientras buscaba una solución a mi problema, y no sé si lo puedeo aplicar.

    Tengo una página index.php con un include de un menu.php. Lo que quería era que al pinchar los enlaces de este menú, se cargaran las páginas en un div “contenidos” que hay en index.php. ¿Se puede emplear este tutorial para hacerlo o mejor lo hago de otra forma?

    Saludos y Gracias

  19. Que pasa si creo dentro de un div varios div dinamicos y luego quiero usar esos Ids para ocultar uno de ellos, puedo obtener el id de un objeto creado dinamicamente?

  20. Weno.. les pediria… por favor a alguien, si me pudiera pasar un manual basico de ajax, ya que mis conocimientos de codigo no son muy amplios y estoy tratando de meterme en el tema. Salu2. lionel. lio.arg@gmail.com

  21. Excelente amigo muy bien explicado felicitaciones.

    Ví el codigo de http://www.mentorprovida.com/php/ajaxr/example.html Quisiera que alguien me lo enviara a mi correo jasonkfm@gmail.com sin embargo este codigo si entiendo bien lo de Ajax puede mejorarse ya que cuando haces click a un elemento de la lista esta viajando (haciendo submit) para traerse los nuevos datos que son los que se muestran al final de la pagina de todas formas me interesa para ver si le puedo hayar solucion a eso, muchas gracias de antemano se despide Jason desde Caracas – Venezuela

  22. sencillo pero muy efectivo…Felicitaciones meta cumplida.

    me gustaria saber como enlazar con PHP y MYSQL para un proyecto que estoy realizando

  23. Rolo » El ejemplo que mencionas es el que puedes descargar de la web de Apple Developer que se menciona en el post…

  24. Muy buen tutorial, felicitaciones al creador, estoy interesado en la tendencia Ajax. No tengo experiencia en ajax, pero si en PHP, CSS, html y otros lenguajes web. Desconosco si ser sumamente necesario un server para programar cosas mas interesantes en Ajax, si la respuesta es “si” los invito a que se contacten conmigo yo me dedico al hospedaje web y podriamos usar el server para “jugar”. Claro que no les cobraría nada. Salu2 desde México

  25. genial, muy buen tutorial para iniciarse, me ha servido de mucha ayuda para empezar con esto del Ajax

  26. Alguien me podria decir como hago q un metodo de java script se ejecuta llamandolo en el onload de una pagina, esta pagina se coloca en un div dentro de otra pagina

  27. Hola, una cuestion como aplico esto a un formulario, por que u simple link funciona sin problemas pagina

    pero en un formulario:

    no funciona

    Isaac

  28. Soy el de antes, se ve que el blog me interpreta el html: el codigoque habia puesto es este:

    “a href=”#” name=”#” onclick=”cargaXML(this.name)” “

    “form action=”#” onsubmit=”cargaXML(this.name)” method=”post” enctype=”multipart/form-data””

    bichomen

  29. Hola, antes que nada, gracias por escribir ejemplos sencillos en tu tutorial. Estube probando tu script pero cuando intenté hacer una aplicación para mi me dejó de funcionar.

    en primer lugar, en mozilla no me punciona si no enlazo con la función de esta manera:

    req.onreadystatechange = processReqChange() (si no pongo los parentesis no me va a la función).

    Mi objetivo era testear por javascript si existia la página y en caso afirmativo abrirla. Con el explorer funcionó, al principio me aparece como readyState 0 o 1, pero al rato daba 4 y podía habrir la page. En mozilla todas las veces me dio readyState 0. Lo feo tambien es que si le suministro una url que no existe, de ves en cuando explorer me da que la conexión existe (readyState ==4).

    estoy usando firefox 1.5.0.6 y explorer 6.0.28. Por favor, te agradecería que me digas en que estoy fallando, gracias

  30. Muy buen tutorial, facil de entender y muy potente para realizar distintas aplicaciones…:-)

  31. Muy buen tutorial, facil de entender y muy potente para realizar distintas aplicaciones…:-)

Comments are closed.