Código Asincrónico AJAX

18-3-2020

Para trabajar con Ajax debemos primeramente create un nuevo objeto del tipo XMLHttpRequest(). Este objeto nos permite generar el pedido (o request) al servidor. Tiene propiedades y métodos que nos van a ayudar a enviar nuestra request y obtener una response del server.

Una de las propiedades en la que debemos detenernos, es readyState. readyState nos dirá en qué estado está la comunicación con el servidor. readyState devuelve siempre un número:

0 -> Instancia creada
1 -> Instancia configurada
2 -> Intercambio de headers entre cliente y servidor
3 -> Transerencia de información
4 -> Comunicación finalizada (ok o no ok)

Un evento útil para trabajar con readyState es readystatechange, que nos permite hacer algo cuando el estado cambia.

//generamos un objeto XMLHttpRequest y lo metemos en la variable xhr
let xhr = new XMLHttpRequest();

//ponemos un escuchador ante el cambio de estado...
xhr.addEventListener("readystatechange", () => {
//si readyState es 4, o sea la comunicación terminó... 
 if (xhr.readyState == 4) {
    //en caso que esa respuesta haya dado un status 200 es decir que haya sido exitosa en encontrar el recurso...
    if (xhr.status == 200) {
      //entonces imprimimos la respuesta
      console.log(xhr.response);
    } else {
      console.log("ERROR! status:", xhr.status);
    }
  }
});

Con las distintas propiedades podemos obtener información que nos permita hacer verificaciones antes de mostrar o trabajar con el contenido.

Cada conexión entre el cliente y el servidor, intercambia headers o encabezados de comunicación. En realidad los headers son generados por la respuesta del servidor, que los envía al cliente.

/* Obtengo los headers de comunicación */
  if (xhr.readyState == 2) {
    let headers = xhr.getAllResponseHeaders();
    console.log(headers)
    //ahora busco un tipo de contenido en especial que me debe responder el header
    //primero lo meto en en la variable tipo
    let tipo = xhr.getResponseHeader("content-type");

// Tengo dos formas de hacerlo: antes de JS6 usábamos indexOf para obtener el índice del elemento que buscamos, y si no lo encuentra devuelve -1:
    if (tipo.indexOf("text/plain") == -1) {
      xhr.abort();
    }
//con JS6 usamos includes que busca un elemento y devuelve, más fácil, true o false.
    if(!tipo.includes('text/plain')) {
      xhr.abort();
  }

Si en lugar de escuchar el estado de la respuesta, por ejemplo, esperando que termine (que sea 4), podemos escuchar el evento load, que se dispara cuando la página cargó, es decir, cuando readyState llega a 4.

xhr.addEventListener('load', () => {
    if(xhr.status == 200) {
        console.log(xhr.response)
    }
})

Una vez que estamos seguros con nuestro escuchador de tener una conexión exitosa y haber recibido loq ue buscábamos, es momento de obtener la información que nos trae, y luego de haber armado todo ello hacer el envío al servidor para que efectivamente se haga el request:

xhr.open("get", "js/texto.txt");
xhr.send();

 

Ejemplo Ajax funcionando

 

//Imaginemos un botón en nuestro html: 

        let btn = document.querySelector('button')

//para que no nos traiga el recurso cada vez que clickeamos el botón, generamos una variable que verifique si el botón ya fué clickeado

        let yaCreado = false

//si el usuario clickea...
btn.addEventListener('click', () => {
    //console.log('Btn Click!')

    //si el botón no fue clickeado...
    if(!yaCreado) {
    //nos conectamos al servidor
         let xhr = new XMLHttpRequest
         //y buscamos el recurso
         xhr.open('get', 'plantilla.html')
         //si la página cargó
         xhr.addEventListener('load', () => {
               //y efectivamente el recurso fué encontrado...
               if(xhr.status == 200) {
                 //metemos la respuesta en una variable
                 let plantilla = xhr.response
                 //creamos un elemento donde mostramos la data que tiene el recurso
                 let div = document.createElement('div') 
                 //metemos el contenidos del recurso allí 
                 div.innerHTML = plantilla 
                 //y lo agregamos al 
                 document.body.appendChild(div) 
                 //y cambiamos el estado del botón para que sepamos que ya fue clickeado 
                 yaCreado = true 
                 } 
        }) 
        //finalmente enviamos la petición 
xhr.send() 
   }
 
})
donde mostraremos la información que tiene el recurso...