1

I'm working on a Node.js/MongoDB based website and i'm trying to upload images directly on server using Express, Jade, and Multer, but no matter what i do, i can't achive to upload the file with extension.

I've got this on my app.js file:

var express = require('express');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var multer = require('multer');

var storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, './uploads')
    },
    filename: function (req, file, cb) {
        cb(null, file.originalname)
    }
});

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


var app = express();

mongoose.connect("mongodb://localhost/primera_pagina");

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(multer({dest: "./uploads"}).single("image_avatar"));


var productSchema = {
    title:String,
    description:String,
    imageURL:String,
    pricing:Number
};

var Product = mongoose.model("Product", productSchema);

app.set("view engine","jade");

app.use(express.static("public"));

app.get("/",function(req,res){

    res.render("index");

});

app.post("/productos",function(req,res){
    if(req.body.password == "123"){
        var data = {
            title: req.body.title,
            description: req.body.description,
            imageURL: "image_avatar",
            pricing: req.body.pricing
        }

        var product = new Product(data);

        console.log(req.file)

    }else{
        res.render("index");
    }


});

app.get("/productos/new",function(req,res){
    res.render("productos/new");
});


app.listen(8080);

Any idea? I've search on Internet and tried every single method to add file extension with multer, but none has worked.

2 Answers2

1

Multer strips the file extension for both security and collision reasons. For a workaround, try this:

var path = require('path')
var multer = require('multer')
var mime = require('mime-types')

var storage = multer.diskStorage({
  destination: './uploads/',
  filename: function (req, file, cb) {
    crypto.pseudoRandomBytes(16, function (err, raw) {
      if (err) return cb(err)

      cb(null, raw.toString('hex') + mime.extension(file.mimetype))
    })
  }
})

var upload = multer({ storage: storage })

(from https://github.com/expressjs/multer/issues/170#issuecomment-123402678)

It assigns a random file name, but keeps the file extension in tact.


You should also be using the authorize field in multer, since it looks like you only want files when the user has the correct password. Do something like this:

var upload = multer({ storage: storage }, limits : { fileFilter: authorize }); 

function authorize(req, file, cb) {
    if (req.body.password == PASS) {
        cb(null, true); //accept
    } else { 
        cb(null, false); //reject
    }
}

This will only save the file to disk if the user has inputted the correct password.

Tennyson H
  • 1,705
  • 15
  • 28
  • 1
    Thanks for your help, but once again, is not working... this is what I get in the log file: { fieldname: 'image_avatar', originalname: 'Tuka_Icono-02.png', encoding: '7bit', mimetype: 'image/png', destination: './uploads', filename: 'bcebdd2d2b44256872177047259d0100', path: 'uploads/bcebdd2d2b44256872177047259d0100', size: 22538 } – Manuel Cárdenas Pérez Feb 19 '16 at 19:06
  • I guess you can infer the extension from the mime-type then using https://www.npmjs.com/package/mime-types. I've updated my answer. – Tennyson H Feb 19 '16 at 19:14
  • 1
    It's not working. Once again my log file: filename: '29704301c5375e3f0c3ac139c6993df5', maybe something wrong anywhere else in my app.js? – Manuel Cárdenas Pérez Feb 19 '16 at 19:29
0

You can pass the right parameters for Multer like this in order to save the file extension:

var multer = require('multer');
var path = require('path')

var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'uploads/')
  },
  filename: function (req, file, cb) {
    cb(null, Date.now() + path.extname(file.originalname)) 
  }
})

var upload = multer({ storage: storage });
Sharhabeel Hamdan
  • 1,273
  • 13
  • 15