Tute 09: Image File upload with Multer - ariffira/node-basic GitHub Wiki

Download my tute08 code and install using npm install

Multer:

  • a middleware
  • multipart/form data

install : npm i --save multer

add in app.js file

const multer = require('multer');
const upload = multer({
    dest: 'upload/',
});

add this routes

// file upload
app.post('/upload', upload.single('my-pic'), (req, res) => {
    res.redirect('/profile');
});

// profile route
app.get('/profile', (req, res)=> {
    res.render('profile')
});

then in html form do this

<form action="/upload" enctype="multipart/form-data" method="post">
    <input type="file" name="my-pic">
    <input type="submit" value="Add My Pic">
</form>

This is very simple. But your image is not perfectly uploaded. no extension.

Lets update code:

Step 01: Configure Multer storage and uploaded file name as unique name

const multer = require('multer');
// multer setting storage
const storage = multer.diskStorage({
    destination: function (req, file, callback) {
        callback(null, 'public/upload/images')
    },
    filename: function (req, file, callback) {
        callback(null, Date.now() + file.originalname)
    }
});

const upload = multer({ storage: storage });

If your public folder not set yet do this:

// set uploads folder
app.use(express.static(__dirname + '/public'));

Step 02: set and update image upload routes and send data to profile page

// file upload routes
app.post('/upload', upload.single('my-pic'), (req, res) => {
    // get temporary file path or destination
    const imageName = req.file.filename;

    console.log(imageName) 

    // check file extension name
    const uploadedFileExt = path.extname(req.file.originalname).toLowerCase();
    // console.log(uploadedFileExt);

    // rename only jpg file else delete from temporary uploads/
    if ((uploadedFileExt == '.jpg') || (uploadedFileExt == '.png')) {
        res.redirect('/profile/' + imageName);
    } else {
        // if not jpg remove file and give a message
        fs.unlink(req.file.path, err => {
            if (err) throw err;
            res.status(403);
            res.contentType("text/plain")
            res.end("Please upload only JPG or PNG file");
        });
    }
});

Step 03: Update your profile routes with params as image

// profile route
app.get('/profile/:imageName', (req, res)=> {
    var imagePath =  '/upload/image/' + req.params.imageName;
    console.log(imagePath);
    res.render('profile', { imagePath: imagePath });
});

Finally, Add this line if you use handlebars in your view to see image

<img src={{imagePath}} width="300" height="300">

Homeworks:

  • You can add this to add only image upload: if (!file.originalname.match(/\.(jpg|jpeg|png|gif)$/)) or
  • You can add filter option in multer storage config like below:
 //A means of ensuring only images are uploaded.
    filename:........
    .............,
    fileFilter: function(req, file, next){
        if(!file){
            next();
        }
        const image = file.mimetype.startsWith('image/');
        if(image){
            console.log('photo uploaded');
            next(null, true);
        }else{
            console.log("file not supported");
            return next();
        }
  • Use Jimp or any other image resizer to resize your image onClick
⚠️ **GitHub.com Fallback** ⚠️