Fetch, Ajax moderno en Javascript

  • Por
Tutorial de introducción a fetch, el nuevo mecanismo de Javascript para realizar solicitudes al servidor de manera asíncrona, lo que se conoce como Ajax.

Fetch es un nuevo API para el acceso a recursos del servidor de manera asíncrona, basado en promesas. Es básicamente la nueva interfaz para realizar funcionalidades Ajax con Javascript, que ya podemos usar para facilitar la organización del código en nuestras aplicaciones.

El acceso a recursos de un servidor de manera asíncrona, comúnmente llamado Ajax, nos permite realizar solicitudes HTTP sin necesidad de recargar toda la página. Tradicionalmente se vienen usando diversos mecanismos para esta tarea, basados en APIs de los navegadores que pueden tener diferencias entre distintos clientes web. Es por ello que muchas veces acabamos usando una librería como jQuery para acceder a las funcionalidades de Ajax.

Fetch pretende ofrecer una nueva interfaz estándar de uso de Ajax, compatible en todos los navegadores, a la vez que permite usar promesas, que nos facilitan la organización del código asíncrono en las aplicaciones. Es un mecanismo disponible en navegadores modernos, que podríamos usar en otros navegadores más antiguos cargando el correspondiente polyfill.

En este artículo veremos unos primeros ejemplos sencillos con Fetch y más adelante hablaremos de usos más avanzados y realizaremos ejemplos más avanzados. Lo que no vamos a explicar es el uso de las promesas de Javascript ES6, ya que ha sido materia de estudio de artículos anteriores. Tampoco vamos a tratar todavía sobre el uso de sus Polyfill y sus diferentes alternativas para compatibilidad, que analizaremos en breve en futuros artículos.

Método fetch()

El método fetch() depende directamente del objeto window del navegador. Su uso más simple consiste en pasarle una URL, cuyo contenido se traerá el cliente web de manera asíncrona.

Nota: Como toda la jerarquía de objetos del navegador comienza en window, podemos opcionalmente invocar a fetch sin mencionar al objeto window.
fetch('test.txt')

La URL a la que estamos accediendo es "test.txt", una URL relativa que supondrá que en nuestro servidor disponemos de un archivo llamado "test.txt" en la misma carpeta donde está la página donde estamos trabajando.

Como ya hemos dicho, fetch basa su trabajo en promesas ES6, por lo que nos devolverá una promesa que podemos tratar tal como estamos acostumbrados a hacer, con el "then" y el "catch".

fetch('test.txt')
  .then(ajaxPositive)
  .catch(showError);

Como sabes, then() nos servirá para definir la función que se encargará de realizar acciones en el caso positivo y catch() para definir una función con código a ejecutar en el caso negativo.

Tratamiento del error con catch()

Comenzamos por ver el código a ejecutar en el caso negativo, que es más sencillo. Simplemente definimos una función que recibirá como parámetro el motivo del error.

function showError(err) { 
  console.log('muestor error', err);
}
Nota: Fíjate que la función showError() fue enviada como parámetro en el catch().

Es muy importante mencionar que fetch(), así como en general todo el trabajo con Ajax, se implementa mediante el protocolo HTTP. Es por ello que, para asegurarnos que los ejemplos con fetch funcionen, tenemos que acceder a la página web que realiza esa solicitud con fetch por medio de HTTP. Es decir, no podríamos simplemente hacer un doble clic sobre un archivo .html y abrir el documento en el navegador con file://. En resumen, debemos necesariamente tener el archivo .html en un servidor web y acceder a él mediante http://.

Si la página desde la que se hace el fetch se accede desde file:// observaremos como la llamada Ajax nos da un error y el flujo de ejecución de nuestro código se va por la parte del catch.

Tratamiento del caso positivo con then()

Cuando se ejecuta la solicitud de manera correcta podemos escribir el código del caso positivo en la función que asignamos al then() asociado al método fetch().

El caso positivo siempre nos devolverá una respuesta del servidor, sobre la que se pueden realizar varias cosas, básicamente saber los detalles derivados del protocolo HTTP de la respuesta y acceder al contenido que el propio servidor nos ha enviado.

La respuesta del servidor la recibimos como parámetro en la función que indicamos para ejecutar en el caso positivo, then(). La respuesta contiene varias propiedades y métodos que podemos usar para realizar diferentes acciones y examinar lo que el servidor nos devolvió. En el siguiente código encontramos un uso básico de ese objeto de respuesta.

Nota: Ten en cuenta que recibir esta respuesta no nos asegura que la solicitud HTTP se completase correctamente. Podría darse el caso que intentamos acceder a un recurso no existente y entonces recibiremos la respuesta, aunque con un código 404 de página no encontrada. Es decir, la respuesta que estamos recibiendo en el then() puede tener, o no, el contenido que estábamos requiriendo. Así que antes de nada tendremos que analizar la respuesta para ver si está o no correcta.
function ajaxPositive(response) {
  console.log('response.ok: ', response.ok);
  if(response.ok) {
    response.text().then(showResult);
  } else {
    showError('status code: ' + response.status);
    return false;
  }
}
Nota: Fíjate que la función ajaxPositive() fue enviada como parámetro en el then() asociado al fetch. Primer código de este artículo.

Por ejemplo, la propiedad "ok" de la respuesta nos ofrece información sobre si la solicitud produjo una respuesta con un código positivo (un status 200 o similar) en el protocolo HTTP. La propiedad "status" nos ofrece el código de respuesta del servidor (200, 404, 500, etc.).

Acceder al texto de la respuesta de Ajax con fetch

El método que nos devuelve el texto del servidor se llama text(). Es un método existente en el objeto de la respuesta recibida. Sin embargo, acceder al contenido de la respuesta, el texto que el servidor nos envía, no es tan trivial. El motivo es que el método text() devuelve otra promesa, lo que nos obliga a tratarla de nuevo con el correspondiente then / catch.

En nuestro código anterior solo estamos tratando el caso positivo, asociando la función "showResult", que será la que se ocupe de ejecutar código cuando el texto de la respuesta ya esté disponible.

La función que asocias al "then" del método text() de la respuesta recibe como parámetro el contenido de texto recibido por el servidor. En nuestro caso habíamos asociado "showResult" y en el código de esa función es donde podremos ver cómo usar el texto de la respuesta.

function showResult(txt) {
  console.log('muestro respuesta: ', txt);
}

Ejemplo completo de Ajax con fetch

Para entender mejor un uso completo de uso de fetch encontrarás ahora el código del ejercicio que hemos usado como base para escribir este artículo.

Por simplificarlo bastante, todos los mensajes de respuesta los enviamos a la consola, por lo que tendrás que abrirla para observar la salida del programa.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Fetch</title>
</head>
<body>
  <button id="btn">Hacer una conexión con Ajax</button>
  
  <script>
  document.addEventListener('DOMContentLoaded', configureAjaxCalls);

  function configureAjaxCalls() {
    document.getElementById('btn').addEventListener('click', function() {
      fetch('test.txt')
        .then(ajaxPositive)
        .catch(showError);
    });

    function ajaxPositive(response) {
      console.log('response.ok: ', response.ok);
      if(response.ok) {
        response.text().then(showResult);
      } else {
        showError('status code: ' + response.status);
      }
    }

    function showResult(txt) {
      console.log('muestro respuesta: ', txt);
    }

    function showError(err) { 
      console.log('muestor error', err);
    }
  }
  </script>
</body>
</html>

Esperamos que entiendas este código y puedas experimentar por ti mismo las funcionalidades detrás del acceso a Ajax con fetch. En siguientes artículos profundizaremos un poco más sobre este mecanismo del navegador.

Autor

Miguel Angel Alvarez

Miguel es fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Comenzó en el mundo del desarrollo web en el año 1997, transformando su hobby en su trabajo.

Compartir

Comentarios

legna

27/10/2017
Compatibilidad Navegadores
El problema que encuentro es la compatibilidad con navegadores, como lo resuelves?