Multer is a middleware that lets us process file uploads with our Express app.
In this article, we’ll look at how to use it to process uploads and process text data in multipart forms.
How to Use it?
We can install it by running:
npm install --save multer
Once it’s installed we have to make a form that has the encoding type multipart/form-data
.
It won’t process any form that’s not multipart, i.e. has the enctype
set to multipart/form-data
.
Simple Usage
The simplest usage is to allow upload of one file at a time. We can do this by calling the multer
function and setting the path to store the uploaded file as follows:
const express = require('express');
const bodyParser = require('body-parser');
const multer = require('multer');
const upload = multer({ dest: './uploads/' });
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static('public'));
app.get('/', (req, res) => {
res.sendFile('public/index.html');
});
app.post('/upload', upload.single('upload'), (req, res) => {
res.send('file uploaded')
});
app.listen(3000, () => console.log('server started'));
Then we can create index.html
in the public
folder and add:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Upload</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="upload" />
<input type='submit' value='Upload'>
</form>
</body>
</html>
The code for index.html
will make the form submit multipart form data.
Also, the value of thename
attribute has to match with the name string that’s passed into the upload.single()
method.
Once the file is upload, a random ID will be generated for the uploaded file’s name.
req.files
will have the file objects and req.body
will have the values of the text fields.
Uploading Multiple Files
We can also process the upload of multiple files with the upload.array
method as follows:
const express = require('express');
const bodyParser = require('body-parser');
const multer = require('multer');
const upload = multer({ dest: './uploads/' });
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static('public'));
app.get('/', (req, res) => {
res.sendFile('public/index.html');
});
app.post('/upload', upload.array('uploads', 5), (req, res) => {
res.send('files uploaded')
});
app.listen(3000, () => console.log('server started'));
Then we have to change index.html
to:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Upload</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="uploads" multiple />
<input type='submit' value='Upload'>
</form>
</body>
</html>
We add the multiple
attribute to the form to enable multiple uploads in addition to using the upload.array
method.
The 5
in the second argument of the upload.array
call is the maximum number of files that we can upload.
Once the file is upload, a random ID will be generated for the uploaded file’s name.
Multiple File Fields
We can enable upload of multiple files as follows:
const express = require('express');
const bodyParser = require('body-parser');
const multer = require('multer');
const upload = multer({ dest: './uploads/' });
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static('public'));
app.get('/', (req, res) => {
res.sendFile('public/index.html');
});
const multiUpload = upload.fields([
{ name: 'photos', maxCount: 3 },
{ name: 'texts', maxCount: 5 }
])
app.post('/upload', multiUpload, (req, res) => {
console.log(req.files);
res.send('files uploaded');
});
app.listen(3000, () => console.log('server started'));
Then when we have the following in public/index.html
:
<!DOCTYPE html>
<html><head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Upload</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head><body>
<form action="/upload" method="post" enctype="multipart/form-data">
<label>Photos</label>
<br>
<input type="file" name="photos" multiple />
<br>
<label>Texts</label>
<br>
<input type="file" name="texts" multiple />
<br>
<input type='submit' value='Upload'>
</form>
</body></html>
We get the files uploaded after we select the files and submit them. The code:
const multiUpload = upload.fields([
{ name: 'photos', maxCount: 3 },
{ name: 'texts', maxCount: 5 }
])
Gets the files from the fields photos
and texts
and upload to 3 and 5 files respectively.
In the console.log
, we see the files of the POST /upload
route that we uploaded.
Upload Nothing
To skip the processing of upload files, we can use the upload.none()
method as follows:
const express = require('express');
const bodyParser = require('body-parser');
const multer = require('multer');
const upload = multer();
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static('public'));
app.get('/', (req, res) => {
res.sendFile('public/index.html');
});
app.post('/submit', upload.none(), (req, res) => {
res.send(req.body)
});
app.listen(3000, () => console.log('server started'));
Then when have the following for public/index.html
:
<!DOCTYPE html>
<html><head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Upload</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head><body>
<form action="/submit" method="post" enctype="multipart/form-data">
<input type="text" name="name" />
<input type='submit' value='Submit'>
</form>
</body></html>
We get the submitted POST body in req.body
as we can see from the response after typing in something and clicking Submit.
Conclusion
Multer is very useful for processing any kind of multipart forms. It can process uploads of a single file or multiple files. It can also process uploads for multiple fields.
The files uploaded are renamed to an automatically generated by default and are stored in the folder that we specified when we called the multer
function to create the middleware.
Also, it can ignore uploaded files and just parse the text request body.