Datos de formulario de varias partes de Axios: envío de archivos a través de un formulario con JavaScript

En este tutproial, aprenda cómo enviar un archivo a través de un formulario HTML usando JavaScript: Axios, Node y Express, a través de ejemplos prácticos de código.

Introducción

Multipart/Form-Data es uno de los tipos de codificación que permite que los archivos se incluyan en los datos de su formulario antes de que se transfieran al servidor para su procesamiento. Se pueden usar otros tipos de codificación para lograr transferencias que no sean de archivos:

  • aplicación/x-www-form-urlencoded - Codifica los datos como una cadena de consulta - separa los pares clave-valor (asignados con =), con símbolos como &.
  • multipart/form-data - Permitir que los archivos se incluyan en los datos de un formulario.
  • texto/sin formato: envía datos como texto sin formato (sin codificación) y se utiliza principalmente para la depuración, no para la producción.

Y cualquiera de esto se puede agregar a una etiqueta de formulario HTML a través del atributo (opcional) enctype:

1
2
<form action="/path/to/api" method="POST" encytpe="ENCTYPE_HERE">
</form>

Funcionan de una manera bastante sencilla, y es probable que los haya visto antes empleados con una etiqueta HTML <form>; sin embargo, el valor predeterminado funciona bien en la mayoría de los casos, por lo que el atributo suele omitirse.

En esta guía, veremos cómo enviar archivos y otros datos de formulario de forma asíncrona con Axios a un servidor Node.js (Express), y cómo recibir estos datos en el backend para su procesamiento.

Instalación de Axios {#instalación de axios}

Axios es un cliente HTTP (asincrónico) basado en Promise, presente y utilizado en muchos proyectos de Node.js. Es bastante común usar Axios para enviar solicitudes HTTP, en lugar de fetch().

If you'd like to read more about sending HTTP requests with fetch() - read our Usando fetch para enviar solicitudes HTTP en JavaScript or Realización de solicitudes HTTP en Node.js con node-fetch!

Para usar Axios en sus proyectos de Node, puede instalarlo fácilmente a través de npm:

1
2
3
$ npm install axios
# OR
$ yarn add axios

Alternativamente, puede incluir su CDN directamente (o descargar sus archivos a su máquina local) e incluir la biblioteca en su marcado de la siguiente manera:

1
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

Establecer el enctype con Axios y HTML

Para enviar datos de varias partes (archivos) a través de datos de formulario, deberá configurar el tipo de codificación. Hay un par de maneras en que puede hacer esto, sin un "ganador" claro o distinto: al final, son funcionalmente equivalentes por solicitud. Con Axios, puede establecer el tipo de codificación global predeterminado:

1
axios.defaults.headers.post['Content-Type'] = 'multipart/form-data';

Esto obliga a que todas las solicitudes de Axios sean del tipo de codificación multipart/form-data. Alternativamente, puede definir el tipo para cada solicitud individual, modificando los “encabezados”:

1
2
3
4
5
axios.post("/path/to/api", data, {
  headers: {
    "Content-Type": "multipart/form-data",
  },
});

O simplemente puede configurar el atributo enctype en la etiqueta <form> de un formulario específico, y Axios simplemente adoptará el tipo de codificación de ese formulario:

1
2
<form action="/some-endpoint" method="HTTP_METHOD" enctype="multipart/form-data">
</form>

Axios + Expreso

Para nuestro ejemplo, crearemos un formulario simple con dos entradas, una para que el usuario envíe su nombre y la otra para que seleccione una imagen de perfil:

1
2
3
4
5
6
7
<form action="/update-profile" method="post">
    <input type="text" name="username" placeholder="Enter name" />
    <input type="file" name="userPicture" />
    <button type="submit">Submit</button>
</form>

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

Sin usar Axios, esto permitiría que se desarrollara el conjunto predeterminado de eventos. Hacer clic en el botón "Enviar" enviaría una solicitud POST al extremo /update-profile de nuestro servidor. Sin embargo, podemos anular este comportamiento predeterminado adjuntando un detector de eventos al botón y evitando los eventos predeterminados.

Nuevamente, enviar solicitudes de Axios implica asincronía, y podemos modificar nuestros encabezados y personalizar la solicitud antes de enviarla. Adjuntemos un detector de eventos, evitemos el comportamiento predeterminado y en su lugar enviemos los datos de nuestro formulario a través de Axios:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<script>

  const form = document.querySelector("form");
  form.addEventListener("submit", (e) => {
    e.preventDefault();
    const formData = new FormData(form);
    axios
      .post("http://localhost:5000/update-profile", formData, {
        headers: {
          "Content-Type": "multipart/form-data",
        },
      })
      .then((res) => {
        console.log(res);
      })
      .catch((err) => {
        console.log(err);
      });
  });
</script>

{.icon aria-hidden=“true”}

Nota: Nuevamente, podría haber establecido el enctype del formulario, o alterado los headers con Axios. La elección está totalmente en ti.

¡Impresionante! Cuando se completa el formulario y se hace clic en el botón "Enviar", la solicitud se reenvía al extremo http://localhost:5000/update-profile, con soporte para cargar archivos. Ahora, definamos el punto final que recibe esta solicitud y la procesa.

Servidor exprés {#Servicio exprés}

Para nuestro backend, la forma más simple y limpia de activar una API REST es a través de Express.js, que se ocupa de la configuración de un servidor y el manejo de solicitudes, lo que le permite concentrarse en el desarrollo en lugar de la configuración.

Si desea leer más sobre cómo crear APIs REST con Node y Express, lea nuestra [Guía para construir una API REST con Node y Express](/construyendo-una-api-de-descanso-con-node-y -Rápido/)!

Express funciona muy bien por sí mismo, pero está destinado a ser mínimo y ampliable con middleware. Se pueden instalar varios middleware simples (o complejos) encima para expandir la funcionalidad principal, cuando sea necesario.

Para usar Express, querremos instalarlo a través de npm. Para un manejo sencillo de la carga de archivos con Express, podemos utilizar el middleware express-fileupload, que también se instala fácilmente a través de npm:

1
$ npm install express express-fileupload 

Ahora, iniciemos un servidor y definamos un punto final que acepte nuestra solicitud POST a /update-profile:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Import the library
const express = require("express");
var fileupload = require("express-fileupload");

// Create app instance
const app = express();

// Register and set up the middleware
app.use(fileupload());
app.use(express.urlencoded({ extended: true }));

// Request handler/endpoint
app.post("/update-profile", (req, res) => {
    let username = req.body.username;
    let userPicture = req.files.userPicture;
    res.send(`
      Your username is: ${username}
      Uploaded image name is: ${userPicture.name}
    `);
});

// Start up the server
app.listen(5000, () => {
    console.log("Server started on port 5000");
});

La solicitud (req) pasada al controlador de solicitudes contiene los datos enviados por nuestro formulario. Su cuerpo contiene todos los datos de los campos que hemos configurado, como el nombre de usuario. Todos y cada uno de los archivos se ubicarán en el campo files del objeto req.

¡Podemos acceder a la entrada nombre de usuario a través de req.body.username, y al archivo cargado a través de req.files.userPicture!

Cuando enviamos el formulario a través de nuestra página HTML, se envía una solicitud a esta API y recibimos la siguiente respuesta en la consola de nuestro navegador:

1
2
Your username is: NAME_YOU_ENTERRED
Uploaded image name is: UPLOADED_FILE_NAME

Además, si registramos req.files.userPicture en la consola, devolverá toda la información sobre nuestro archivo, como el nombre del archivo, el tipo de codificación y otra información relacionada con el archivo.

Conclusión

En esta guía, echamos un vistazo al atributo enctype y explicamos cómo funciona. Luego exploramos cómo configurar enctype con Axios, una biblioteca HTTP asincrónica popular, y enviar solicitudes POST que contienen datos de archivos/partes múltiples.

Finalmente, creamos una API REST para manejar la solicitud y aceptar el archivo entrante y otros datos del formulario.

{.icon aria-hidden=“true”}

El código fuente está disponible en GitHub.