Introducción
Contenido
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.
Te puede interesar:Promesas en Node.js.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.
Te puede interesar:Construyendo una API REST con Node y ExpressCreamos 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:
Te puede interesar:Desplegando una aplicación Node.js en un Droplet de DigitalOcean con Dockerconst 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.
Te puede interesar:Usar fetch para enviar solicitudes HTTP en JavaScript.