Cargue la gestión de archivos en Node.js con Express y Multer

C

Introducción

Los usuarios no solo consumen datos, también producen y cargan datos. Pueden enviar datos a través de aplicaciones como mensajeros o correo electrónico a destinatarios específicos o cargar archivos a redes sociales y plataformas de transmisión de datos como Facebook o YouTube.

Dicho esto, casi todos los sitios web interactivos actuales admiten la carga de archivos.

Bibliotecas de carga de archivos

Hay varias bibliotecas de nodes disponibles en NPM que pueden simplificar el proceso de validación y carga de archivos al servidor. Entre ellos, es la opción más popular en estos días. Multer, Formidabley Multipartidista.

Todos tienen versiones estables y son compatibles con una comunidad en línea de desarrolladores de código abierto.

¿Qué es Multer?

Multer son artículos básicos populares de Node.js que se utilizan para manejar multipart/form-data solicitud. El lo usa ayudante de mesero analizar los datos que ha recibido a través de un formulario HTML. Esto mejora en gran medida su rendimiento porque el módulo busboy no tiene rival para el análisis de datos de formularios.

Multer nos proporciona disciplina y flexibilidad en nuestro manejo multipart/form-data aplicaciones: obtenemos información detallada sobre cada archivo cargado, la capacidad de agregar un motor de almacenamiento personalizado, la validación de archivos de acuerdo con nuestras necesidades, la capacidad de establecer límites en los archivos cargados, etc.

Arreglo del proyecto

Dado que no almacenaremos nuestras imágenes en una base de datos, sino en una carpeta simple para mayor nitidez y simplicidad, hagamos otra carpeta en nuestra carpeta de proyecto y asígnele un nombre, digamos, uploads.

Ahora instalemos Express:

$ npm i express

Y finalmente, instalemos Multer:

$ npm i multer

Implementacion de proyecto

En este punto, estamos listos para escribir algo de código, comenzando con los formularios HTML que usaremos para recolectar información.

Comenzamos con el formulario para subir un archivo individual:

<form method="POST" action="/upload-profile-pic" enctype="multipart/form-data">
    <div>
        <label>Select your profile picture:</label>
        <input type="file" name="profile_pic" />
    </div>
    <div>
        <input type="submit" name="btn_upload_profile_pic" value="Upload" />
    </div>
</form>

Y luego con un formulario que nos permite subir varios archivos:

<form method="POST" action="/upload-multiple-images" enctype="multipart/form-data">
    <div>
        <label>Select multiple images:</label>
        <input type="file" name="multiple_images" multiple />
    </div>
    <div>
        <input type="submit" name="btn_upload_multiple_images" value="Upload" />
    </div>
</form>

Puede colocar estos formularios en páginas separadas o en la misma. Para el propósito de este tutorial, son uno en una fila:

Los formularios HTML son bastante simples, asumiendo multipart/form-data y orientar las funciones adecuadas que se ocupan de sus aplicaciones.

Aplicación express

Con nuestros formularios listos, podemos trabajar en la lógica real para cargar y validar archivos a través de Express.

Creamos un archivo llamado app.js en la raíz del proyecto y comience importando los módulos requeridos:

const express = require('express');
const multer = require('multer');
const path = require('path');

Ahora creemos nuestra aplicación Express:

const app = express();

Y finalmente, configuremos el puerto en el que se ejecutará:

const port = process.env.PORT || 3000;

El es public los archivos estáticos que queremos servir están en el directorio de nuestra carpeta raíz, así que configurémoslo como un directorio estático usando express.static:

app.use(express.static(__dirname + '/public'));

En este punto, definamos la ubicación de almacenamiento de nuestras imágenes:

const storage = multer.diskStorage({
    destination: function(req, file, cb) {
        cb(null, 'uploads/');
    },

    // By default, multer removes file extensions so let's add them back
    filename: function(req, file, cb) {
        cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname));
    }
});

Y finalmente, ejecutemos la aplicación usando el puerto que configuramos anteriormente:

app.listen(port, () => console.log(`Listening on port ${port}...`));

Validación y carga de archivos

Por razones básicas de seguridad, necesitaremos validar los archivos antes de subirlos a nuestros servidores. Editemos el app.js archivo y agregue ambas funciones:

app.post('/upload-profile-pic', (req, res) => {
    // 'profile_pic' is the name of our file input field in the HTML form
    let upload = multer({ storage: storage, fileFilter: helpers.imageFilter }).single('profile_pic');

    upload(req, res, function(err) {
        // req.file contains information of uploaded file
        // req.body contains information of text fields, if there were any

        if (req.fileValidationError) {
            return res.send(req.fileValidationError);
        }
        else if (!req.file) {
            return res.send('Please select an image to upload');
        }
        else if (err instanceof multer.MulterError) {
            return res.send(err);
        }
        else if (err) {
            return res.send(err);
        }

        // Display uploaded image for user validation
        res.send(`You have uploaded this image: <hr/><img src="${req.file.path}" width="500"><hr /><a href="./">Upload another image</a>`);
    });
});

Aquí, aceptamos una solicitud HTTP POST, que contiene la información de la imagen incrustada. La función que realmente se encarga de la funcionalidad de carga es multer().single() método.

Puede que hayas notado la fileFilter: helpers.imageFilter pero no el helpers archivo. Así que creemos un nuevo archivo en nuestro directorio de proyectos y asígnele un nombre helpers.js. Escribiremos aquí un código que se utilizará para comprobar si la imagen es el archivo enviado o no.

const imageFilter = function(req, file, cb) {
    // Accept images only
    if (!file.originalname.match(/.(jpg|JPG|jpeg|JPEG|png|PNG|gif|GIF)$/)) {
        req.fileValidationError="Only image files are allowed!";
        return cb(new Error('Only image files are allowed!'), false);
    }
    cb(null, true);
};
exports.imageFilter = imageFilter;

Por supuesto, para usar este módulo, necesitaremos importarlo en la parte superior de nuestro app.js archivo:

const helpers = require('./helpers');

Ahora podemos ejecutar nuestra aplicación y validar que está funcionando correctamente:

Cargar varios archivos

Cargar varios archivos es básicamente lo mismo que cargar un solo archivo. Aunque, en lugar del multer().single() función, usamos la multer().array() función:

app.post('/upload-multiple-images', (req, res) => {
    // 10 is the limit I've defined for number of uploaded files at once
    // 'multiple_images' is the name of our file input field
    let upload = multer({ storage: storage, fileFilter: helpers.imageFilter }).array('multiple_images', 10);

    upload(req, res, function(err) {
        if (req.fileValidationError) {
            return res.send(req.fileValidationError);
        }
        else if (...) // The same as when uploading single images

        let result = "You have uploaded these images: <hr />";
        const files = req.files;
        let index, len;

        // Loop through all the uploaded images and display them on frontend
        for (index = 0, len = files.length; index < len; ++index) {
            result += `<img src="${files[index].path}" width="300" style="margin-right: 20px;">`;
        }
        result += '<hr/><a href="./">Upload more images</a>';
        res.send(result);
    });
});

Y ahora, valide si todo está funcionando correctamente:

Conclusión

Los usuarios no solo consumen datos, sino que los producen y, en muchos casos, tienen que subirlos a un servidor web. Pueden enviar datos a través de aplicaciones como mensajeros o correo electrónico a destinatarios específicos, o pueden cargar archivos a redes sociales y plataformas de transmisión de datos como Facebook o YouTube.

En este artículo, usamos Express.js y la biblioteca Multer para manejar la funcionalidad básica de carga de archivos en una aplicación web simple.

.

About the author

Ramiro de la Vega

Bienvenido a Pharos.sh

Soy Ramiro de la Vega, Estadounidense con raíces Españolas. Empecé a programar hace casi 20 años cuando era muy jovencito.

Espero que en mi web encuentres la inspiración y ayuda que necesitas para adentrarte en el fantástico mundo de la programación y conseguir tus objetivos por difíciles que sean.

Add comment

Sobre mi

Últimos Post

Etiquetas

Esta web utiliza cookies propias para su correcto funcionamiento. Al hacer clic en el botón Aceptar, aceptas el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad