Перейти до основного вмісту

Multer

Multer — це проміжне ПЗ (middleware) фреймворка Express, яка використовується при завантаженні файлів для обробки multipart/form-data. По суті є обгорткою над низькорівневим пакетом busboy, що дозволяє використовувати його максимально ефективно. Multer не обробляє жодний інший тип форм, крім multipart/form-data.

Встановлення

npm install -S multer

Multer додає об'єкт body та об'єкт file (або files) всередину об'єкту request. Об'єкт body містить значення текстових полів форми, об'єкт file (files) містить файл або файли, що завантажуються через форму.

Повний код нашої програми наступний.

const createError = require('http-errors');
const express = require('express');
const path = require('path');
const fs = require('fs').promises;
const app = express();
const multer = require('multer');
const uploadDir = path.join(process.cwd(), 'uploads');
const storeImage = path.join(process.cwd(), 'images');

const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, uploadDir);
},
filename: (req, file, cb) => {
cb(null, file.originalname);
},
limits: {
fileSize: 1048576,
},
});

const upload = multer({
storage: storage,
});

app.post('/upload', upload.single('picture'), async (req, res, next) => {
const { description } = req.body;
const { path: temporaryName, originalname } = req.file;
const fileName = path.join(storeImage, originalname);
try {
await fs.rename(temporaryName, fileName);
} catch (err) {
await fs.unlink(temporaryName);
return next(err);
}
res.json({ description, message: 'Файл успішно завантажено', status: 200 });
});

// catch 404 and forward to error handler
app.use((req, res, next) => {
next(createError(404));
});

app.use((err, req, res, next) => {
res.status(err.status || 500);
res.json({ message: err.message, status: err.status });
});

const isAccessible = path => {
return fs
.access(path)
.then(() => true)
.catch(() => false);
};

const createFolderIsNotExist = async folder => {
if (!(await isAccessible(folder))) {
await fs.mkdir(folder);
}
};

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

app.listen(PORT, async () => {
createFolderIsNotExist(uploadDir);
createFolderIsNotExist(storeImage);
console.log(`Server running. Use on port:${PORT}`);
});

Він досить схожий з попереднім прикладом тому зосередимося на основних відмінностях.

Пакет надає наступну інформацію щодо кожного завантажуваного файлу:

КлючОписЗауваження
fieldnameІм'я поля, задане у формі
originalnameІм'я файлу на комп'ютері користувача
encodingКодування файлу
mimetypeMime-тип файлу
sizeРозмір файлу в байтах
destinationКаталог, де буде збережено файлDiskStorage
filenameІм'я файлу без destinationDiskStorage
pathПовний шлях до завантажуваного файлуDiskStorage
bufferBuffer з усього файлуMemoryStorage

Створюємо двигун дискового простору DiskStorage

const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, uploadDir);
},
filename: (req, file, cb) => {
cb(null, file.originalname);
},
limits: {
fileSize: 1048576,
},
});

За допомогою опцій, розташування destination та ім'я файлу filename ми визначаємо, де буде знаходитись файл після завантаження.

  • destination використовується, щоб задати каталог, в якому будуть розміщені файли.
  • filename використовується, щоб визначити, як буде названо файл усередині каталогу. Якщо ім'я файлу filename не задано, то як говорилося в попередньому розділі кожному файлу буде надано випадкове ім'я без розширення файлу.

У параметрах кожної функції є запит (req) та набір інформації про файл (file, дивись попередню таблицю)

Також присутній об'єкт limits встановлює обмеження. Він повністю збігається з методами пакету busboy, переглянути повний список методів. В нашому прикладі ми встановили максимальний розмір файлу в 1 Мбайт.

Ми створюємо екземпляр multer

const upload = multer({
storage: storage,
});

Далі ми використовуємо проміжне ПЗ

upload.single('picture');

Воно завантажує один файл з ім'ям picture у тимчасову папку uploads, а інформація про файл буде збережена в req.file

Всередині обробника ми переносимо файл до папки постійного зберігання images

Повний код прикладу на Github Gist