web-dev-qa-db-fra.com

Renommer un fichier téléchargé à l'aide de Multer ne fonctionne pas (Express.js)

J'essaie de télécharger un fichier à partir d'un formulaire HTML à l'aide d'Express.js et de Multer. J'ai réussi à enregistrer le fichier à l'emplacement souhaité (un dossier nommé uploads).

Cependant, j'aimerais renommer le fichier lors de son téléchargement car, par défaut, Multer lui attribue un nom étrange, tel que:

5257ee6b035926ca99923297c224a1bb

Peut-être un horodatage hexadécimal ou autre, mais j'ai besoin d'un nom plus explicite pour pouvoir appeler un script ultérieurement.

J'ai suivi l'explication trouvée ici mais cela ne fait rien de plus qu'avant: télécharger le fichier avec le nom hexa.

De plus, les deux événements onFileUploadStart et onFileUploadComplete ne semblent jamais être déclenchés car je n'ai rien enregistré dans ma console.

J'utilise deux fichiers distincts pour le serveur et le routage:

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;

J'ai fouillé mais je n'arrive pas à comprendre le problème car je suis assez novice dans Node.js et JavaScript en général.

Merci pour votre aide les gars!

10
Vincent Montalieu

L'utilisation de Multer a changé.

Actuellement, le constructeur Multer n'accepte que trois options:

  1. dist/stockage 
  2. fileFilter
  3. limites

maintenant renommer, onFileUploadStart, onFileUploadComplete ne fonctionnerait pas.

cependant, renommer peut être fait en utilisant 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 })

regardez ces liens:

20
Gaurav Gupta

Je sais que ce post est daté. Je veux contribuer à ceux qui peuvent arriver plus tard. Vous trouverez ci-dessous un script de serveur fonctionnel complet permettant de gérer plusieurs images téléchargées avec des noms d'images aléatoires et une extension de fichier.

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);
});
6
Thomas Thai

nous donnons un nom aléatoire à classer à l'aide de date et ajoutons l'extension de fichier d'origine à l'aide de file.mimetype

essayez console.log (file.mimetype), vous obtiendrez le nom du fichier et son extension séparés par un '/', puis je le scinderai en un tableau et en extrairai l'extension.

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 })
3

essayez de cette façon que j'utilise 

  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 })
2
Pradeep Saini

Personnellement, j'ai implémenté les solutions suivantes, qui génèrent un nom aléatoire pour les fichiers et ajoutent l'extension de fichier d'origine (je suppose que mon extension est postérieure à la dernière.)

var path = require('path');

    var options = multer.diskStorage({ destination : 'uploads/' ,
      filename: function (req, file, cb) {
        cb(null, (Math.random().toString(36)+'00000000000000000').slice(2, 10) + Date.now() + path.extname(file.originalname));
      }
    });

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

    router.post('/cards', upload.fields([{ name: 'file1', maxCount: 1 }, { name: 'file2', maxCount: 1 }]), function(req, res, next) {
    /*
      handle files here
      req.files['file1']; //First File
      req.files['file2']; //Second File
      req.body.fieldNames;//Other Fields in the form

    */
    });


Dans la documentation MULTER, vous trouverez ceci: 

Le moteur de stockage sur disque vous donne un contrôle total sur le stockage des fichiers sur disque.

Il existe deux options disponibles, destination et nomfichier . Elles sont les deux fonctions qui déterminent où le fichier doit être stocké.

Remarque: Vous êtes responsable de la création du répertoire lorsque vous fournissez la destination en fonction. En passant une ficelle, multer fera Assurez-vous que le répertoire est créé pour vous.

nom_fichier est utilisé pour déterminer le nom du fichier dans le fichier dossier. Si aucun nom de fichier n'est donné, chaque fichier se verra attribuer un nom aléatoire cela n'inclut aucune extension de fichier.

Remarque: Multer n’ajoutera aucune extension de fichier pour vous, votre fonction devrait renvoyer un nom de fichier complet avec une extension de fichier.

1
user2517028

Le fichier a une structure comme celle-ci: 

{
"fieldname": "avatar",
"originalname": "somefile.pdf",
"encoding": "7bit",
"mimetype": "application/pdf",
"destination": "./uploads",
"filename": "36db44e11b83f4513188f649ff445a2f",
"path": "uploads\\36db44e11b83f4513188f649ff445a2f",
"size": 1277191

}

L'exemple suivant enregistre le fichier avec son nom d'origine une extension et non avec le nom étrange comme c'est le cas par défaut. (Au lieu de "file.originalname" vous pouvez le sauvegarder comme vous le souhaitez)

var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, './uploads') //Destination folder
  },
  filename: function (req, file, cb) {
    cb(null, file.originalname) //File name after saving
  }
})

var upload = multer({ storage: storage })
0
runha