In an earlier article, I explained how to upload files in Node.js and Express with express-fileupload
middleware.
Today, we will go through another popular middleware called Multer for handling single and multiple file uploads with Express and Node.js. We will save the uploaded files on the local file system.
What is Multer?
As I said earlier, Multer is an Express middleware for handling multipart/form-data
requests. When a user uploads a file to the server, the browser automatically encodes the request as multipart/form-data
. Multer makes it easy to handle such a request on the server.
Project Setup
Let us create a new directory for our demo project and switch to it by typing the command following:
$ mkdir express-multer && cd express-multer
Next, create the package.json
file by running the following command:
$ npm init -y
Now install Multer, Express, and other required dependencies:
$ npm install express multer body-parser cors morgan --save
Basic Express Server
Let us now create a basic Express server. First of all, create an index.js
file:
$ touch index.js
Copy and paste the following code into it to initialize all the modules and start the Express app:
index.js
const express = require('express')
const multer = require('multer')
const cors = require('cors')
const bodyParser = require('body-parser')
const morgan = require('morgan')
// create an express app
const app = express()
// upload file path
const FILE_PATH = 'uploads'
// configure multer
const upload = multer({
dest: `${FILE_PATH}/`
})
// enable CORS
app.use(cors())
// add other middleware
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.use(morgan('dev'))
// start the app
const port = process.env.PORT || 3000
app.listen(port, () => console.log(`App is listening on port ${port}.`))
The above code configures Multer to accept multipart/form-data
file upload requests and save them to the uploads
folder, enables Cross-Original Resource Sharing (CORS), and starts the Express server at port 3000
.
Upload Single File
Let us create our first route in the Express application to allow users to upload their profile images:
app.post('/upload-avatar', upload.single('avatar'), async (req, res) => {
try {
const avatar = req.file
// make sure the file is available
if (!avatar) {
res.status(400).send({
status: false,
data: 'No file is selected.'
})
} else {
// send response
res.send({
status: true,
message: 'File is uploaded.',
data: {
name: avatar.originalname,
mimetype: avatar.mimetype,
size: avatar.size
}
})
}
} catch (err) {
res.status(500).send(err)
}
})
The above function receives an HTTP POST request. upload.single('avatar')
is Multer middleware that accepts a single file with the field name avatar
, uploads it to the destination folder, and adds a file
property to the req
object.
We can access the uploaded file using the req.file
property. It has the following important information:
fieldname
— The name of the field used in the formoriginalname
— The name of the file on the user's computerencoding
— Encoding type of the filemimetype
— Mime type of the filesize
— The size of the file in bytes
We simply use these properties in the single file upload route to return the uploaded file details.
Upload Multiple Files
Let us add another route. This time for uploading multiple files at once:
app.post('/upload-photos', upload.array('photos', 8), async (req, res) => {
try {
const photos = req.files
// check if photos are available
if (!photos) {
res.status(400).send({
status: false,
data: 'No photo is selected.'
})
} else {
let data = []
// iterate over all photos
photos.map(p =>
data.push({
name: p.originalname,
mimetype: p.mimetype,
size: p.size
})
)
// send response
res.send({
status: true,
message: 'Photos are uploaded.',
data: data
})
}
} catch (err) {
res.status(500).send(err)
}
})
Uploading multiple files with Multer is similar to a single file upload with a few changes. The Multer middleware now accepts an array of files as input, with a maximum of 8 files at once. The field name is also changed to photos
.
Testing the Application
Start the Express application by running the following command in your terminal from the root directory:
$ node index.js
It will start the application at port 3000
. Let us use Postman for sending HTTP multipart/form-data
requests:
Single File
Multiple Files
File Size Limit
If you want to limit the file size, add the limits
property to the object that is passed to multer()
:
const upload = multer({
dest: `${FILE_PATH}/`,
limits: {
files: 5, // allow up to 5 files per request,
fileSize: 2 * 1024 * 1024 // 2 MB (max file size)
}
})
Filter File Type
Sometimes we want to allow users to upload images only. You can easily limit the file types by using the fileFilter
property:
const upload = multer({
dest: `${FILE_PATH}/`,
limits: {
files: 5, // allow up to 5 files per request,
fileSize: 2 * 1024 * 1024 // 2 MB (max file size)
},
fileFilter: (req, file, cb) => {
// allow images only
if (!file.originalname.match(/\.(jpg|jpeg|png|gif)$/)) {
return cb(new Error('Only image are allowed.'), false)
}
cb(null, true)
}
})
Source code: Download the complete source code from GitHub available under MIT license.
Conclusion
That's all folks for today. You have learned how to upload files using Express and Multer in Node.js. Multer is an easy-to-use Express middleware for handling multipart/form-data
requests.
Check out the official documentation for more configuration options.
✌️ Like this article? Follow me on Twitter and LinkedIn. You can also subscribe to RSS Feed.