Fetch API + AJAX: Cómo enviar peticiones desde el navegador

Fetch API + AJAX: Cómo enviar peticiones desde el navegador

Fetch API es la API del navegador (y ahora, de Node.js) que nos facilita la realización de peticiones al servidor sin necesidad de recargar la página del usuario/a. Mejora la UX de nuestras aplicaciones y facilita la escritura y mantenimiento de nuestro código, pues se basa en promesas ahorrándonos la necesidad de escribir callback functions. […]

Categorías: AJAX

Adrián Garzón Ximénez - Desarrollador Fullstack


Fetch API es la API del navegador (y ahora, de Node.js) que nos facilita la realización de peticiones al servidor sin necesidad de recargar la página del usuario/a. Mejora la UX de nuestras aplicaciones y facilita la escritura y mantenimiento de nuestro código, pues se basa en promesas ahorrándonos la necesidad de escribir callback functions.

En el artículo introductorio a AJAX expliqué que AJAX nos permite romper el flujo tradicional de comunicación a través de Internet. Al implementar AJAX en una página web, podemos enviar peticiones al servidor y que estas se resuelvan en segundo plano. Luego podemos utilizar esa información para modificar la interfaz del usuario/a.

El resultado es que el usuario/a no tiene que esperar a que su navegador haga la petición, el servidor la procese y responda y entonces se recargue su página. Utilizando AJAX la experiencia de usuario es mucho más fluida.

Para ilustrar cómo emplear esta tecnología, usé la clase XMLHttpRequest. El objetivo de esta clase es, precisamente, realizar peticiones al servidor sin refrescar la página. Pero hoy quiero profundizar en un método alternativo y, en mi opinión, más potente y sencillo: fetch().

¿Qué es fetch() y cuándo utilizarlo?

fetch() es un método de JavaScript implementado en diferentes interfaces, que incluyen Window y WorkerGlobalScope. Por tanto, podemos usarlo en diferentes fuentes. Sin embargo, ten en cuenta que estamos hablando de APIs del navegador. Es decir, si estamos escribiendo en Node.js, el método fetch() no estará disponible (aunque hay librerías alternativas) salvo que estés utilizando una versión posterior a la 17.5.

El objetivo del método fetch es ofrecer una alternativa a XMLHttpRequest basada en promesas en lugar de en callbacks. Escribiré un artículo sobre ello, pero de momento puedes encontrar información online sobre qué es el callback hell y entenderás por qué es mejor esta interfaz.

En pocas palabras, la API fetch() nos ofrece una interfaz mucho más sencilla y limpia para realizar llamadas asíncronas con JavaScript.

¿Cómo se utiliza la API fetch()?

fetch() es un método que requiere un argumento: la ruta hasta el recurso que queremos alcanzar. En respuesta nos devolverá una promesa, que se resolverá en cuanto se reciba la respuesta a la petición.

Además de este parámetro obligatorio, podemos proporcionarle un segundo argumento que es un objeto de inicialización, con el que podremos configurar el tipo de petición que estamos haciendo.

Si necesitamos interrumpir la petición podemos utilizar las APIs AbortController o AbortSignal (no disponibles en todos los navegadores). Debemos recordar que el método fetch() solo va a rechazar la promesa en caso de encontrar un error de red. De modo que, incluso en los casos en que recibamos respuestas como 404 la promesa se resolverá y, por tanto, necesitaremos comprobar las propiedades ok y status de la respuesta para comprobar si hemos alcanzado los recursos que solicitábamos.

La configuración de las llamadas fetch()

El objeto de configuración de las llamadas fetch(), que podemos pasar como un segundo parámetro, tiene como principales opciones:

  • method. Permite definir el método a ejecutar, que por defecto es GET.
  • headers. Permite configurar las cabeceras de la petición.
  • body. Introduce un cuerpo a la petición, siempre que el método lo permita (por ejemplo, no podríamos hacerlo en una petición GET o HEAD). Los tipos de contenido que admite la interfaz son:
    • Blob.
    • BufferSource.
    • FormData.
    • URLSearchParams.
    • ReadableStream.
    • String.

Además de estas opciones básicas, tenemos otras de configuración avanzada, que abordaré en otro artículo.

La respuesta de las llamadas fetch()

Una vez recibida la respuesta del servidor, fetch() resolverá su promesa mediante un objeto Response. También puede interrumpirse la petición mediante el método abort() (que forma parte de la API AbortController) o en casos de error de tipado (por ejemplo, si configuramos una cabecera con un nombre o un valor inválido).

La interfaz Headers

Headers es una de las piezas clave de la API fetch(), ya que nos permite realizar acciones sobre las cabeceras de las peticiones y respuestas HTTP. Tales acciones incluyen recabar, configurar, añadir o eliminar cabeceras de la lista headers de la petición.

El objeto Headers contiene una lista (inicialmente vacía) de pares nombre-valor. Sus métodos incluyen:

  • append()
  • delete()
  • entries()
  • forEach()
  • get()
  • has()
  • keys()
  • set()
  • values()

Los nombres de estos métodos son bastante descriptivos. Lo único que conviene tener en cuenta es que:

  • append y set funcionan de forma muy similar. Su diferencia es que si el encabezado aceptara varios valores, append añadirá los nuevos valores proporcionados, mientras que set sobreescribirá los antiguos.
  • Los iteradores (entries, keys, values) devuelven una lista de valores ordenada lexicográficamente, combinando los valores de los headers duplicados.
  • Todos estos métodos pueden devolver un TypeError si hacemos referencias a nombres de encabezados inválidos o tratamos de mutar un encabezado con una guardia inmutable.

La interfaz Request

Esta es otra de las piezas clave de la API fetch, y representa la petición que mandamos al servidor. Podemos crearla mediante el constructor Request(), aunque normalmente lo haremos mediante el objeto de inicialización que pasemos al método fetch().

Incluye un amplio catálogo de propiedades y métodos que analizaré en otra ocasión, cuando profundice en el uso de la interfaz (puedes consultarlos en MDN). Sus métodos nos permiten, principalmente, dar formato de salida al cuerpo de la petición, mientras que sus propiedades suelen definirse en el antedicho objeto de inicialización.

La Interfaz Response

En tercer lugar, la interfaz Response constituye la última pieza clave de la API fetch. De nuevo, la API nos proporciona un constructor y una serie de propiedades (que normalmente definiremos en el objeto de inicialización) y de métodos (cuya labor principal es cambiar el formato del cuerpo de la respuesta).

¿Por qué utilizar las interfaces headers, request y response al llamar a fetch?

Como digo, en la mayoría de las ocasiones no vas a utilizar (al menos no de forma directa) las interfaces Headers, Request y Response. Sin embargo, pueden resultarte útiles tanto para escribir código reutilizable (si las características de diferentes llamadas coinciden) como para configurar y/o transformar la información que intercambias con el servidor.

Especificación de fetch()

Puedes consultar la especificación de la API fetch() en su página oficial.

Mantente al tanto de mis próximos recursos sobre AJAX

  • ¿Qué es AJAX y cómo y cuándo usarlo?
  • Fetch API.
  • Eventos enviados por el servidor.
  • Cómo conectar AJAX y PHP.
  • Cómo gestionar XML y datos binarios con AJAX.
  • La API de lectura de archivos en AJAX.
  • ¿Qué es axios, cómo utilizarlo y cuáles son sus ventajas?