Як обробляти завантаження файлів в Express.js за допомогою Multer?
Завантаження файлів в Express.js
Express.js не обробляє завантаження файлів нативно. Multer є найпопулярнішим проміжним програмним забезпеченням для обробки multipart/form-data (завантаження файлів).
Налаштування
bash
npm install multerОсновне завантаження файлів
js
const multer = require('multer');
// Зберігати в пам'яті (для обробки/завантаження в хмару)
const upload = multer({ storage: multer.memoryStorage() });
// Завантаження одного файлу
app.post('/upload/avatar', upload.single('avatar'), (req, res) => {
console.log(req.file);
// {
// fieldname: 'avatar',
// originalname: 'photo.jpg',
// mimetype: 'image/jpeg',
// size: 123456,
// buffer: <Buffer ...>
// }
res.json({ message: 'Завантажено!', file: req.file.originalname });
});Зберігання на диску з користувацьким іменуванням
js
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/');
},
filename: (req, file, cb) => {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
const ext = path.extname(file.originalname);
cb(null, file.fieldname + '-' + uniqueSuffix + ext);
}
});
const upload = multer({ storage });
app.post('/upload', upload.single('file'), (req, res) => {
res.json({ path: req.file.path });
});Кілька файлів
js
// Кілька файлів з однаковим ім'ям поля
app.post('/upload/photos', upload.array('photos', 10), (req, res) => {
console.log(req.files); // Масив об'єктів файлів
res.json({ count: req.files.length });
});
// Кілька полів
const cpUpload = upload.fields([
{ name: 'avatar', maxCount: 1 },
{ name: 'gallery', maxCount: 8 }
]);
app.post('/upload/profile', cpUpload, (req, res) => {
console.log(req.files['avatar']); // Масив з 1 файлом
console.log(req.files['gallery']); // Масив з до 8 файлів
});Валідація файлів
js
const upload = multer({
storage: multer.memoryStorage(),
limits: {
fileSize: 5 * 1024 * 1024, // максимальний розмір 5МБ
files: 5 // максимум 5 файлів
},
fileFilter: (req, file, cb) => {
const allowedTypes = ['image/jpeg', 'image/png', 'image/webp'];
if (allowedTypes.includes(file.mimetype)) {
cb(null, true);
} else {
cb(new Error('Дозволені тільки зображення JPEG, PNG та WebP'), false);
}
}
});
// Обробка помилок Multer
app.post('/upload', upload.single('image'), (req, res) => {
res.json({ success: true });
});
app.use((err, req, res, next) => {
if (err instanceof multer.MulterError) {
if (err.code === 'LIMIT_FILE_SIZE') {
return res.status(400).json({ error: 'Файл занадто великий (макс 5МБ)' });
}
return res.status(400).json({ error: err.message });
}
next(err);
});Завантаження в хмару (приклад S3)
js
const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3');
const upload = multer({ storage: multer.memoryStorage() });
const s3 = new S3Client({ region: 'us-east-1' });
app.post('/upload', upload.single('file'), async (req, res) => {
const key = `uploads/${Date.now()}-${req.file.originalname}`;
await s3.send(new PutObjectCommand({
Bucket: process.env.S3_BUCKET,
Key: key,
Body: req.file.buffer,
ContentType: req.file.mimetype
}));
res.json({ url: `https://${process.env.S3_BUCKET}.s3.amazonaws.com/${key}` });
});Підсумок
| Функція | Реалізація |
|---|---|
| Один файл | upload.single('field') |
| Кілька файлів | upload.array('field', max) |
| Кілька полів | upload.fields([...]) |
| Обмеження розміру файлу | limits: { fileSize: ... } |
| Валідація типу | fileFilter callback |
| Пам'яткове зберігання | multer.memoryStorage() |
| Дискове зберігання | multer.diskStorage({...}) |
Порада для виробництва: Завжди перевіряйте тип і розмір файлу. Зберігайте файли в хмарному сховищі (S3, GCS, Azure Blob), а не на диску. Використовуйте підписані URL-адреси для безпечного доступу. Обробляйте зображення асинхронно (зменшення розміру, стиснення) за допомогою бібліотек, таких як
sharp.
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.