Como descargar archivos con Axios

viernes, 27 de noviembre de 2020

Aprende a descargar archivos con JavaScript y Axios, también con una adaptación del código a ReactJS

El problema que se podrá solucionar en este post es poder descargar archivos enviados desde alguna API , para ello vamos a usar Axios y aprender conceptos y funciones que nos da el navegador como createObjectURL , Blob y Promesas o Funciones Asíncronas , para esta práctica podemos hacerlo en CodePen o en local usando algún empaquetador como Esbuild , Parcel , Rollup o Webpack . Para ello en el HTML ponemos la CDN de Axios o puedes usar npm de Node de la siguiente mantera

SHELL
      
      npm i axios
    

En el archivo JS enlazado a un archivo HTML ponemos el siguiente condigo:

JS
      
      import axios from "axios"
const getUrlFile = (url) => {
  const config = {
    url,
    method: "GET",
    responseType: "blob",
  }

  return axios
    .request(config)
    .then(({ data }) => URL.createObjectURL(new Blob([data])))
    .catch(console.log)
}

document.addEventListener("DOMContentLoaded", async () => {
  const linkToDownloadImage = document.createElement("a")
  linkToDownloadImage.innerText = "download"
  const dowloadUrl = await getUrlFile(
    "https://images.unsplash.com/photo-1461749280684-dccba630e2f6?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80"
  )
  linkToDownloadImage.setAttribute("href", dowloadUrl)
  linkToDownloadImage.setAttribute("download", "download.jpg")
  document.body.appendChild(linkToDownloadImage)
})
    

Este código lo hace es crear un enlace para descargar, para ello primero hace una petición al servidor donde se aloje el archivo, por ello ponemos una constante config en la función getUrlFile, donde esta la url de la petición, el método que se va a hacer al servidor ( métodos HTTP ) y el formato de la respuesta que se espera, luego la información que responde el servidor se convierte en un objeto Blob y por último se retorna una URL con el objeto, esta URL se puede mostrar con un

JS
      
      console.log(URL.createObjectURL(new Blob([data])))
    

Y aunque no se pueda ver por el tipo, con la propiedad download de la etiqueta

HTML
      
      <a ... dowload="filname.download-extension" />
    

Este atributo es el nombre como se va a llamar al descargar el archivo por lo cual se puede hacer una función que retorne la extensión y el nombre, eso se los dejo como desafío.

React

Para ReactJS vamos a aprender y usar el concepto de Hooks y Custom Hooks , para poder usar versiones mayores a 16, esta solo es una implementación básica del código que ya hicimos, para ello en un proyecto de React crearemos un archivo llamado useDownloadFile.js, y podremos el siguiente código

JSX
      
      import * as React from "react"
import axios from "axios"

export const useDownloadFile = (url) => {
    const [downloadUrl, setDownloadUrl] = React.useState(null)
    const config = {
        url,
        method: "GET",
        responseType: "blob"
    }
    React.useEffect(() => {
        (async () => {
            try {
                const {data} = await axios.request(config)
                const url = URL.createObjectURL(new Blob([data])))
                setDownloadUrl(url)
            }catch(e) {
                console.log(e)
            }
        })();
    },[])
    return downloadUrl
}
    

La implementación del custom hook se usaría en un componente funcional así

JSX
      
      import * as React from "react"
import { useDownloadFile } from "useDownloadFile"

export default const Downloader = ({url}) => {
    const downloadUrl = useDownloadFile(url)
    return (
        <a donwnload="download.zip" href={downloadUrl}>
            {url}
        </a>
        )
}
    

Y eso sería todo el ejemplo de como descargar archivos con Axios con vanilla JS y ReactJS, esto no permite sabe como funciona nuestro código y no tener que depender de librerías de terceros

Lee más artículos