skip to Main Content

I am developing an Express.js application and trying to add the facility of image upload by Multer. I am getting some issues, so any kind of help will be appreciated.

Problem:
The file doesn’t upload, however it says "Error: Images Only!" when I’m uploading a .jpg or .png file.
If no file is selected, it must be "No file selected!" on the page, but somehow it does not want to work.
What I’ve Tried:
Checks the file types and extensions in the checkFileType function.
Ensured that the enctype attribute of the form is set to multipart/form-data.

Question: What could be happening with the image upload? How would I go about fixing this error and why would it not produce the right messages?
Any kind of help/suggestions would be greatly appreciated!
Thanks in advance!

const express = require('express');
const multer = require('multer');
const path = require('path');

const app = express();

// Set storage engine
const storage = multer.diskStorage({
  destination: './uploads/',
  filename: function(req, file, cb) {
    cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname));
  }
});

// Initialize upload
const upload = multer({
  storage: storage,
  limits: { fileSize: 1000000 },
  fileFilter: function(req, file, cb) {
    checkFileType(file, cb);
  }
}).single('myImage');

// Check file type
function checkFileType(file, cb) {
  // Allowed ext
  const filetypes = /jpeg|jpg|png|gif/;
  // Check ext
  const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
  // Check mime
  const mimetype = filetypes.test(file.mimetype);

  if (mimetype && extname) {
    return cb(null, true);
  } else {
    cb('Error: Images Only!');
  }
}

// Public folder
app.use(express.static('./public'));

// Routes
app.post('/upload', (req, res) => {
  upload(req, res, (err) => {
    if (err) {
      res.render('index', {
        msg: err
      });
    } else {
      if (req.file == undefined) {
        res.render('index', {
          msg: 'No file selected!'
        });
      } else {
        res.render('index', {
          msg: 'File uploaded!',
          file: `uploads/${req.file.filename}`
        });
      }
    }
  });
});

// Start server
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server started on port ${PORT}`));

**Index.html Code
**

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Image Upload</title>
</head>
<body>
  <h1>Upload an Image</h1>
  <form action="/upload" method="POST" enctype="multipart/form-data">
    <input type="file" name="myImage">
    <input type="submit" value="Upload">
  </form>
  <% if (typeof msg != 'undefined') { %>
    <p><%= msg %></p>
  <% } %>
  <% if (typeof file != 'undefined') { %>
    <img src="<%= file %>" alt="Uploaded Image">
  <% } %>
</body>
</html>



2

Answers


  1. Everything is fine in the original code!

    The only very minor missing fixed below.

    The code fixes the mimetypes checking issue. Please check the same code with the original. In the original code, it is incorrectly referring to the variable filetypes. Please comment in case clarifications are required.

    // Check file type
    function checkFileType(file, cb) {
      // Allowed ext
      const filetypes = /jpeg|jpg|png|gif|txt/;
      // Allowed mime
      const mimetypes = /image/jpeg|image/png|image/gif/;
      // Check ext
      const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
      // Check mime
      const mimetype = mimetypes.test(file.mimetype);
    
      if (mimetype && extname) {
        return cb(null, true);
      } else {
        cb('Error: Images Only!');
      }
    }
    
    Login or Signup to reply.
  2. The fixed Code – full listing:

    With respect to the full intended functionalities, I have fixed some other issues as well. The following fixed code has been tested and found working. It uploads images successfully and displays the same in the Browser as well.

    Prerequisites :

    1. ejs NPM module is to be installed.
    2. the destination folder uploads has been moved to public folder

    Please comment in case clarifications about the fixed code are required.

    server.js

    const express = require('express');
    const multer = require('multer');
    const path = require('path');
    
    const app = express();
    app.engine('html', require('ejs').__express);
    
    app.set('views', './public');
    app.set('view engine', 'html');
    
    // Set storage engine
    const storage = multer.diskStorage({
      destination: './public/uploads/',
      filename: function (req, file, cb) {
        cb(
          null,
          file.fieldname + '-' + Date.now() + path.extname(file.originalname)
        );
      },
    });
    
    // Initialize upload
    const upload = multer({
      storage: storage,
      limits: { fileSize: 1000000 },
      fileFilter: function (req, file, cb) {
        checkFileType(file, cb);
      },
    }).single('myImage');
    
    // Check file type
    function checkFileType(file, cb) {
      // Allowed ext
      const filetypes = /jpeg|jpg|png|gif|txt/;
      // Allowed mime
      const mimetypes = /image/jpeg|image/png|image/gif/;
      // Check ext
      const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
      // Check mime
      const mimetype = mimetypes.test(file.mimetype);
    
      if (mimetype && extname) {
        return cb(null, true);
      } else {
        cb('Error: Images Only!');
      }
    }
    
    // Public folder
    app.use(express.static('./public', { index: false }));
    
    app.get('/', (req, res) => {
      res.render('index');
    });
    
    // Routes
    app.post('/upload', (req, res) => {
      upload(req, res, (err) => {
        if (err) {
          res.render('index', {
            msg: err, 
          });
        } else {
          if (req.file == undefined) {
            res.render('index', {
              msg: 'No file selected!',
            });
          } else {
            console.log('hits');
            res.render('index', {
              msg: 'File uploaded!',
              file: `uploads/${req.file.filename}`,
            });
          }
        }
      });
    });
    // Start server
    const PORT = process.env.PORT || 5000;
    app.listen(PORT, () => console.log(`Server started on port ${PORT}`));
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search