yooo its me
the writter of this blog
today blog is all about multer yes that module which is kinda having 3 or 4 million download a week yes it has
so let see what i am going to cover in this blog
1) how file transfer from frontend to backend
2) what is multer
3) how to use multer
4) kinda eveyrthing about multer and how to use it
first let biginner
1) how file travels from frontend to backend
Normal HTTP requests usually send text like this
{
"name": "shivam"
}
which is done by express by adding things like
app.use(express.json());
and
app.use(express.urlencoded());
for text-based data.
This is easy.
But files are NOT text.
A PNG file is raw binary bytes:
89 50 4E 47 ...
So browsers needed a special way to send everything in proper way:
- text
- files
- metadata
all together in ONE request.
and that will be done using:
multipart/form-data
why called multipart?
because it contain multi form data π
yes this is why it is called like that
Now Letβs Break This Down
Part 1
------WebKit123
Content-Disposition: form-data; name="username"
shivam
This means:
{
username: "shivam"
}
Part 2 (File)
------WebKit123
Content-Disposition: form-data; name="image"; filename="cat.png"
Content-Type: image/png
This is metadata.
It tells:
- field name = image
- filename = cat.png
- mime type = image/png
Then comes:
(binary bytes)
Actual file data.
How Data Actually Travels
HTTP body travels as STREAMS
NOT like a giant packet.
Instead:
Chunk 1
Chunk 2
Chunk 3
Chunk 4
Like:
------WebKit123
Content-Dispo
then:
sition: form-data;
then:
name="image"
Everything arrives gradually.
Node.js Receives It as Stream
Inside Node.js req is actually a readable stream.
You can literally do:
req.on("data", chunk => {
console.log(chunk);
});
Example you may see:
<Buffer 2d 2d 2d 2d 57 65 62 4b>
These are raw bytes.
now the best part comes
how a developer should handle this
see express is not having anything inbuilt to handle this
but there is one module:
multer
it helps us convert that raw bit into proper data
kinda like this:
{
fieldname: 'image',
originalname: 'cat.png',
encoding: '7bit',
mimetype: 'image/png',
destination: 'uploads/',
filename: 'a8f91c.png',
path: 'uploads/a8f91c.png',
size: 34567
}
let see how multer does that
Multer acts as Middleware between request and route handler.
multer parse this stream manually like:
- Reads chunks
- Detects boundaries
- Separates parts
- Reads headers
- Extracts metadata
- Writes file bytes to disk
How File Is Recreated
Suppose multer extracts:
89 50 4E 47 ...
(this data is after cleaning all the other data this is only the file data)
These are PNG bytes.
It simply writes them into a file using:
fs.writeFile()- or stream pipe
Because files ARE just bytes.
yes it is that simple π
SUPER IMPORTANT UNDERSTANDING
A file is NOT special.
A file is just:
Raw bytes + metadata
Example:
cat.png
is just:
[bytes] stored on disk
now this is how you implment multer code
first : Install Multer
npm install multer
Step 2: Basic Express Setup
like Create a server.js file and write this code inside it
Code:
const express = require("express");
const multer = require("multer");
const app = express();
app.listen(3000, () => {
console.log("Server running");
});
Step 3: Create Uploads Folder
Inside project create a /uploads folder (basically here we are going to save the data)
project/
β
βββ uploads/
βββ server.js
βββ package.json
inshort: This (/uploads) folder stores uploaded files.
Step 4: Basic Multer Setup
as u can sence the multer is a function and we are destcting it and giving the dest paramter a value
const upload = multer({
dest: "uploads/"
});
this is Very basic configuration.
What dest Does ?
it just say store data inside uploads
dest: "uploads/"
means:
"Store uploaded files inside uploads folder"
Step 5: Single File Upload
app.post("/upload", upload.single("image"), (req, res) => {
res.send("File uploaded");
});
first Understanding upload.single()
upload.single("image")
it means:
- Accept only one file from frontend
- frontend Input field name must be "image"
this is how Frontend HTML Form look likes
<form action="/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="image" />
<button type="submit">
Upload
</button>
</form>
Important thing to notice:
enctype
This is very critical
enctype="multipart/form-data"
Without this File upload fails.
after all this thing Uploaded file appears inside uploads/
Example:
8f3a12d8a91b2c.png
Multer auto-generates random names by default.
this is how you Access Uploaded File Info
After upload req.file contains file metadata.
Example:
console.log(req.file);
Example req.file Object
{
fieldname: 'image',
originalname: 'photo.png',
encoding: '7bit',
mimetype: 'image/png',
destination: 'uploads/',
filename: 'a83b12d81.png',
path: 'uploads/a83b12d81.png',
size: 12000
}
Step 6: Custom Storage Configuration
Basic dest works
But usually developers need:
- Custom names
- Better folder control
Use:
diskStorage()
Custom Storage Setup
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "uploads/");
},
filename: function (req, file, cb) {
cb(null, Date.now() + "-" + file.originalname);
}
});
first Understand destination()
destination(req, file, cb)
its just work same as dest it define where the folder should be kept
second think to notice is Understanding filename()
filename(req, file, cb)
so using this we can make your own custom file name
Use Date.now()
because Without unique naming:
image.png
image.png
image.png
Files might overwrite each other.
Using Date.now() prevents collisions.
Connect Storage to Multer
const upload = multer({
storage: storage
});
Complete Single Upload Example
const express = require("express");
const multer = require("multer");
const app = express();
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "uploads/");
},
filename: function (req, file, cb) {
cb(null, Date.now() + "-" + file.originalname);
}
});
const upload = multer({ storage });
app.post("/upload", upload.single("image"), (req, res) => {
console.log(req.file);
res.send("Upload successful");
});
app.listen(3000);
Multiple File Uploads
Sometimes users upload multiple files.
Example:
- Product gallery
- Multiple PDFs
- Photo collections
Use upload.array() it basically help to take multiple file from frontend
Example
app.post("/uploads", upload.array("images", 5), (req, res) => {
console.log(req.files);
res.send("Files uploaded");
});
upload.array("images", 5)
basically means:
- Field name = "images"
- Maximum 5 files
Frontend will handle it like this
<input type="file" name="images" multiple />
for accessing Single upload we can use req.file
but for Multiple uploads we can use req.files
because files become an array
3) Uploading Different Fields
so now comes when the user upload data from diff types like JPG , PNG , pdf ,etc so to handle that we can use upload.fields()
Example
app.post("/profile", upload.fields([
{ name: "avatar", maxCount: 1 },
{ name: "resume", maxCount: 1 }
]), (req, res) => {
console.log(req.files);
res.send("Uploaded");
});
this is how u can access it
req.files.avatar
req.files.resume
File Validation
Very important.
now there are some precaution u can take like Never trust uploads blindly.
1) Restrict File Types
in this only certain file type are allowed to be entered into the server
this is how u can implement that
const fileFilter = (req, file, cb) => {
if (file.mimetype.startsWith("image")) {
cb(null, true);
}
else {
cb(new Error("Only images allowed"));
}
};
Connect Filter
const upload = multer({
storage,
fileFilter
});
File Size Limits
2) Prevent huge uploads.
see the stoarage has a limit and if user uplaod data which is in high amount there is a huge possiblity that stoarage limit will get hit so to restrict that we can use limits
like this
const upload = multer({
storage,
limits: {
fileSize: 5 * 1024 * 1024
}
});
5MB limit
3) Serving Uploaded Files
Uploading alone is not enough
Browser must access files too then we can use the express.static() function
any folder name passed inside static the data inside that folder will be accessable to the user
app.use("/uploads", express.static("uploads"));
Access File via URL
Suppose file:
uploads/photo.png
URL:
http://localhost:3000/uploads/photo.png
Now browser can open uploaded image.
Folder Structure
project/
β
βββ uploads/
β βββ image1.png
β βββ image2.jpg
β
βββ server.js
βββ package.json
Common Multer Methods
| Method | Purpose |
|---|---|
| single() | One file |
| array() | Multiple files |
| fields() | Multiple named fields |
| none() | Only text fields |
| any() | Accept all files |
What is upload.any() ?
upload.any() accepts every uploaded file.
really Not recommended for beginners like there will be so many issue u cannot imagine stik to the traditional part
Common Beginner Mistakes
1. Forgetting uploads Folder
Multer cannot save files without giving a proper place to store it
2. Wrong Field Name
Frontend:
name="photo"
Backend:
upload.single("image")
Upload will fails.
Names must match.
3. Missing enctype
( ooh i have done this so many times)
Without multipart/form-data file upload breaks.
rember this properly
4. Forgetting express.static()
Files upload successfully but URLs fail.
5. Using Original Filenames
( atleast use Date.now()) dont be lazy
Upload Flow Diagram
User Selects File
β
Browser Sends multipart/form-data
β
Multer Middleware Executes
β
File Saved in uploads/
β
req.file Created
β
Route Handler Executes
β
Response Sent Back
Final Understanding
Multer is middleware that helps Express handle:
multipart/form-data
It processes uploaded files, stores them, and makes file metadata available inside request objects.
so this is the end of the blog if u liked the blog with comment it down and if there is something bad just let me know
and also like the blog follow for more such blog
bye bye
Top comments (0)