Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Renaming an uploaded file using Multer doesn't work (Express.js)

I'm trying to upload a file from a HTML form using Express.js and Multer. I've managed to save the file to the desired location (a folder named uploads).

However, I'd like to rename the file while uploading it because, by default, Multer gives it a strange name such as:

5257ee6b035926ca99923297c224a1bb

Might be a hexadecimal time stamp or so but I need a more explicit name in order to call a script on it later.

I've followed the explanation found here but it doesn't do anything more than it used to: uploading the file with the hexa name.

Also, the two events onFileUploadStart and onFileUploadComplete never seem to be triggered as I don't get anything logged in my console.

I am using two separate files for the server and the routing:

app.js

/**
 * Dependencies
 */

var express = require('express');
var path = require('path');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

/**
 * Importation of routes
 */
var routes = require('./routes/index');
var recog = require('./routes/recog');

/**
 * Express
 */
var app = express();

app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

// pour contrer les erreurs de cross domain
app.use(function (req, res, next) {

    // Website you wish to allow to connect
    res.setHeader('Access-Control-Allow-Origin', '*');

    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');

    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    res.setHeader('Access-Control-Allow-Credentials', true);

    // Pass to next layer of middleware
    next();
});

/**
 * Routes
 */
app.use('/', routes);
app.use('/recog', recog);

module.exports = app;

recog.js

/**
 * Requirements
 */
var express = require('express');
var router = express.Router();
var multer = require('multer');
var uploads = multer({
    dest: 'uploads/',
    rename: function (fieldname, filename) {
        console.log("Rename...");
        return filename + Date.now();
    },
    onFileUploadStart: function () {
        console.log("Upload is starting...");
    },
    onFileUploadComplete: function () {
        console.log("File uploaded");
    }
});

/**
 * Upload d'une image
 */
router.post('/upload', uploads.single('image'), function (req, res, next) {
    console.log("Front-end is calling");
    res.json({status: 'success', data: 'Fichier chargé.\nOrgane sélectionné : ' + req.body.organ});
});

module.exports = router;

I have been digging around but I can't figure out what the problem is as I am quite new to Node.js and JavaScript in general.

Thanks for your help guys!

like image 589
Vincent Montalieu Avatar asked Aug 24 '15 14:08

Vincent Montalieu


4 Answers

The usage for Multer has changed.

Currently Multer constructor accepts only three options:

  1. dist/storage
  2. fileFilter
  3. limits

now rename, onFileUploadStart, onFileUploadComplete would not work.

however renaming can be done using DiskStorage

var storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, '/tmp/my-uploads')
    },
    filename: function (req, file, cb) {
        cb(null, file.fieldname + '-' + Date.now())
  }
})

var upload = multer({ storage: storage })

have a look at these links:

  • https://github.com/expressjs/multer
  • multer callbacks not working ?
like image 100
Gaurav Gupta Avatar answered Nov 13 '22 13:11

Gaurav Gupta


I know this post is dated. I want to contribute to those who may arrive later. Below is a full functional server script to handle multiple uploaded pictures with random saved pictures names and file extension.

var express = require("express");
var multer = require("multer");
var app = express();
var path = require("path");
var uuid = require("uuid");

// Allow cross origin resource sharing (CORS) within our application
app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
});

var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'uploadedimages/')
  },
  filename: function (req, file, cb) {
    cb(null, uuid.v4() + path.extname(file.originalname));
  }
})

var upload = multer({ storage: storage })

// "files" should be the same name as what's coming from the field name on the client side.
app.post("/upload", upload.array("files", 12), function(req, res) {
    res.send(req.files);
    console.log("files = ", req.files);
});

var server = app.listen(3000, function() {
    console.log("Listening on port %s...", server.address().port);
});
like image 28
Thomas Thai Avatar answered Nov 13 '22 14:11

Thomas Thai


try this way which i'm using

  var storage = multer.diskStorage({
    destination: function (req, file, cb) {
      cb(null, 'uploads/')
    },
    filename: function (req, file, cb) {
      console.log(file);
      var fileObj = {
        "image/png": ".png",
        "image/jpeg": ".jpeg",
        "image/jpg": ".jpg"
      };
      if (fileObj[file.mimetype] == undefined) {
        cb(new Error("file format not valid"));
      } else {
        cb(null, file.fieldname + '-' + Date.now() + fileObj[file.mimetype])
      }
    }
  })

  var upload = multer({ storage: storage })
like image 5
Pradeep Saini Avatar answered Nov 13 '22 13:11

Pradeep Saini


we give a random name to file with the help of date and appends the original file extension with help of file.mimetype

try console.log(file.mimetype) you will get the file name and extension separated by '/' then I split it to array and fetch the extension from it. Try the below code.

let storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, './uploads')
  },
  filename: function (req, file, cb) {
    let extArray = file.mimetype.split("/");
    let extension = extArray[extArray.length - 1];
    cb(null, file.fieldname + '-' + Date.now()+ '.' +extension)
  }
})
const upload = multer({ storage: storage })
like image 4
VISHNU Avatar answered Nov 13 '22 13:11

VISHNU