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 | Кодування файлу | |
mimetype | Mime-тип файлу | |
size | Розмір файлу в байтах | |
destination | Каталог, де буде збережено файл | DiskStorage |
filename | Ім'я файлу без destination | DiskStorage |
path | Повний шлях до завантажуваного файлу | DiskStorage |
buffer | Buffer з усього файлу | 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