Manejo de cargas de archivos en formularios usando Express

Cómo administrar el almacenamiento y manejo de archivos cargados a través de formularios, en Express

Este es un ejemplo de un formulario HTML que permite a un usuario cargar un archivo:

<form method="POST" action="/submit-form" enctype="multipart/form-data">
  <input type="file" name="document" />
  <input type="submit" />
</form>

No olvides agregarenctype="multipart/form-data"al formulario, o los archivos no se cargarán

Cuando el usuario presione el botón enviar, el navegador automáticamente hará unPOSTsolicitud a la/submit-formURL en el mismo origen de la página. El navegador envía los datos contenidos, no codificados como de forma normalapplication/x-www-form-urlencoded, pero comomultipart/form-data.

En el lado del servidor, el manejo de datos de varias partes puede ser complicado y propenso a errores, por lo que vamos a utilizar una biblioteca de utilidades llamadaformidable.Aquí está el repositorio de GitHub, tiene más de 4000 estrellas y está bien mantenido.

Puedes instalarlo usando:

npm install formidable

Luego inclúyelo en tu archivo Node.js:

const express = require('express')
const app = express()
const formidable = require('formidable')

Ahora, en elPOSTpunto final en el/submit-formruta, creamos una nueva forma Formidable usandoformidable.IncomingForm():

app.post('/submit-form', (req, res) => {
  new formidable.IncomingForm()
})

Después de hacerlo, debemos poder analizar el formulario. Podemos hacerlo de forma sincrónica proporcionando una devolución de llamada, lo que significa que todos los archivos se procesan y, una vez que se hace formidable, los pone a disposición:

app.post('/submit-form', (req, res) => {
  new formidable.IncomingForm().parse(req, (err, fields, files) => {
    if (err) {
      console.error('Error', err)
      throw err
    }
    console.log('Fields', fields)
    console.log('Files', files)
    for (const file of Object.entries(files)) {
      console.log(file)
    }
  })
})

O puede usar eventos en lugar de una devolución de llamada. Por ejemplo, para recibir una notificación cuando se analiza cada archivo u otros eventos, como la finalización del procesamiento del archivo, la recepción de un campo que no es un archivo o si se produce un error:

app.post('/submit-form', (req, res) => {
  new formidable.IncomingForm().parse(req)
    .on('field', (name, field) => {
      console.log('Field', name, field)
    })
    .on('file', (name, file) => {
      console.log('Uploaded file', name, file)
    })
    .on('aborted', () => {
      console.error('Request aborted by the user')
    })
    .on('error', (err) => {
      console.error('Error', err)
      throw err
    })
    .on('end', () => {
      res.end()
    })
})

Cualquiera que sea la forma que elija, obtendrá uno o más objetos Formidable.File, que le brindan información sobre el archivo cargado. Estos son algunos de los métodos que puede llamar:

  • file.size, el tamaño del archivo en bytes
  • file.path, la ruta en la que se escribe el archivo
  • file.name, el nombre del archivo
  • file.type, el tipo MIME del archivo

La ruta por defecto es la carpeta temporal y se puede modificar si escucha lafileBeginevento:

app.post('/submit-form', (req, res) => {
  new formidable.IncomingForm().parse(req)
    .on('fileBegin', (name, file) => {
        file.path = __dirname + '/uploads/' + file.name
    })
    .on('file', (name, file) => {
      console.log('Uploaded file', name, file)
    })
    //...
})

Descarga mi gratisManual de Express.js


Más tutoriales rápidos: