Concept
Multipart Form Data
Standard JSON body parsers (express.json()) cannot parse files. Uploading files requires the HTTP request to use the multipart/form-data encoding type, which splits the payload into boundaries separating fields and raw file binaries.
Using Multer Middleware
Multer is the standard Express middleware for handling multipart/form-data. It intercepts incoming file streams and writes them either to memory (as Buffers) or straight to disk:
import express from 'express';
import multer from 'multer';
const upload = multer({ dest: 'uploads/' }); // Temp storage folder
const app = express();
// Single file upload route
app.post('/profile/avatar', upload.single('avatar'), (req, res) => {
// req.file contains file metadata
// req.body contains text fields
console.log(req.file);
res.status(200).send('Upload completed');
});Memory Storage vs Disk Storage
- Disk Storage (
diskStorage): Multer writes files directly to the server's hard drive as they arrive in chunks. Recommended for large files (videos, PDFs) to prevent server memory exhaustion. - Memory Storage (
memoryStorage): Multer stores the file as a raw buffer in RAM. Useful for small files (avatars) that need immediate upload to cloud storage (like AWS S3).
Common Mistakes
1. Storing uploaded files in memory without size limits
If you use memory storage (multer.memoryStorage()) and a user uploads a 1GB file, Node's memory heap balloons, causing the server to crash with out-of-memory errors. Always enforce file size limits in Multer options.
2. Trusting the client-provided file extension
Accepting files based on client-provided attributes (like file.originalname) is a security risk. An attacker can upload a malicious executable file disguised with an image extension. Always validate the file's Magic Bytes (actual file headers) using a library like file-type.
Best Practices
- Set Strict Limits: Enforce maximum file size limits and file counts using the
limitsoptions:const upload = multer({ dest: 'uploads/', limits: { fileSize: 5 * 1024 * 1024 } // 5MB limit }); - Filter File Types: Implement filter validations to reject unapproved file types:
const fileFilter = (req, file, cb) =>
