Image Upload with Node and Multer
Sat, Dec 3, 2016
This tutorial provides an end to end walkthrough of uploading images in Node with Multer.
To make things simple I am providing an app-template and complete code. Feel free to use the template or an app that you are working on.
I am using Multer 1.2.0 and Node 6.4.0.
- Install Multer, Mime, and Cryto and save to dependencies.
- Require depencies in route `index.js`
- Create a form in `index.ejs`
- Before we can write our upload route, we need to configure Multer's storage. Multer ships with two different storage engines, `DiskStorage` and `MemoryStorage`. I will be using `DiskStorage` which gives you full control over storing files to disk.
- Write upload route
`npm install -S multer`
`npm install -S mime`
`npm install -S crypto`
var express = require('express'),
router = express.Router(),
mime = require('mime'),
multer = require('multer');
<form action="/upload" enctype="multipart/form-data" method="POST">
Select an image to upload:
<input name="image" type="file" />
<input type="submit" value="Upload Image" />
</form>
The form enctype
must be multipart/form-data
, which is the encoding used for forms that upload files. The enctype
specifies how the form-data is encoded when it is submitted to a server.
When submitted, the form will send a POST request to our upload route. We will construct the route in a later step.
Create a folder called uploads
in public
.
In index.js
underneath your require statements, write the following.
var storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, 'public/uploads/')
},
filename: function(req, file, cb) {
crypto.pseudoRandomBytes(16, function(err, raw) {
cb(null, raw.toString('hex') + Date.now() + '.' + mime.extension(file.mimetype));
});
}
});
var upload = multer({
storage: storage
});
The two options for DiskStorage
, destination
and filename
, are functions that determine where the file should be stored. As their name’s suggest, destination determines the upload location and filename determines the filename.
Multer does not provide a file extension for the upload, so the filename function must return a filename with an extension. Filename uses Crypto
to generate a random name and uses Mime
to determine the correct file extension. Generating a random filename prevents collisions if two files are uploaded with the same name. While not required, this is good practice.
upload
will be called to upload an image.
// POST Upload Image
router.post('/upload', upload.single("image"), function(req, res) {
res.send('<img src="/uploads/' + req.file.filename + '" />');
});
You should be all set, but if there are any issues please comment.
Sources
Multer Issue: Files are uploading as ‘file without its extension