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