File Uploads
Accepting files from clients - multer middleware, handling multipart form data, file validation, and storing uploads locally or in cloud storage.
What it is, in plain English: File uploads use a special request encoding called multipart/form-data, which express.json() cannot parse -- it's designed for binary file content, not JSON. Multer is the standard Express middleware for handling multipart uploads: it parses the incoming file data, makes it available on req.file (single) or req.files (multiple), and can validate file type/size before your route handler ever runs.
Why express.json() can't handle file uploads
File uploads use a different request format called multipart/form-data --
it can mix text fields and binary file content in one request. express.json()
only understands JSON text, so a separate middleware is needed: multer.
Basic setup -- a single file upload
# npm install multerimport multer from "multer";
const upload = multer({ dest: "uploads/" }); // saves files to an "uploads" folder
app.post("/upload", upload.single("avatar"), (req, res) => {
// "avatar" must match the form field name the client used
console.log(req.file);
// { fieldname: "avatar", originalname: "photo.jpg", mimetype: "image/jpeg",
// path: "uploads/a1b2c3...", size: 204800 }
res.json({
filename: req.file.filename,
size: req.file.size,
});
});<!-- The HTML form a client would submit from: -->
<form action="/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="avatar" />
<button type="submit">Upload</button>
</form>
<!-- enctype="multipart/form-data" is REQUIRED for file uploads -->Multiple files
// Multiple files under the SAME field name:
app.post("/gallery", upload.array("photos", 10), (req, res) => {
// req.files is an ARRAY (not req.file) when using .array()
res.json({ uploaded: req.files.length });
});
// Multiple DIFFERENT field names:
app.post("/profile", upload.fields([
{ name: "avatar", maxCount: 1 },
{ name: "coverPhoto", maxCount: 1 },
]), (req, res) => {
// req.files.avatar[0], req.files.coverPhoto[0]
res.json({ avatar: req.files.avatar[0].filename });
});Restricting file types and size
const upload = multer({
dest: "uploads/",
limits: { fileSize: 5 * 1024 * 1024 }, // 5MB max
fileFilter: (req, file, cb) => {
const allowed = ["image/jpeg", "image/png", "image/webp"];
if (!allowed.includes(file.mimetype)) {
return cb(new Error("Only JPEG, PNG, and WebP images allowed"));
}
cb(null, true); // accept the file
},
});
Try It Yourself (Node.js logic)
Official Sources
- Multer Documentation
- MDN Web Docs — Using FormData Objects
- OWASP — File Upload Cheat Sheet
- AWS SDK for JavaScript — S3 Client
The Codex links only to official documentation. No third-party tutorials.