Переименование загруженного файла с помощью Multer не работает (Express.js)

Я пытаюсь загрузить файл из HTML-формы с помощью Express.js и Multer. Мне удалось сохранить файл в нужном месте (папка с именем uploads).

Однако, я бы хотел переименовать файл во время его загрузки, потому что по умолчанию Multer дает ему странное имя, например:

5257ee6b035926ca99923297c224a1bb

Возможно, это будет шестнадцатеричная метка времени или так, но мне нужно более явное имя, чтобы позднее вызвать script.

Я следил за найденным объяснением здесь, но он не делает ничего больше, чем он использовал для: загрузки файла с именем hexa.

Кроме того, два события onFileUploadStart и onFileUploadComplete никогда не срабатывают, так как я ничего не регистрировал на своей консоли.

Я использую два отдельных файла для сервера и маршрутизацию:

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;

Я копался, но не могу понять, в чем проблема, поскольку я совершенно новичок в Node.js и JavaScript вообще.

Спасибо за помощь, ребята!

Ответ 1

Использование для Multer изменилось.

В настоящее время конструктор Multer принимает только три варианта:

  • dist/storage
  • FileFilter
  • пределы

теперь переименовать, onFileUploadStart, onFileUploadComplete не будет работать.

однако переименование может быть выполнено с помощью 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 })

ознакомьтесь с этими ссылками:

Ответ 2

Я знаю, что это сообщение датировано. Я хочу внести вклад в тех, кто может приехать позже. Ниже приведен полный функциональный сервер script для обработки нескольких загруженных изображений со случайными именами сохраненных изображений и расширением файла.

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

Ответ 3

мы даем случайное имя в файл с помощью даты и добавляем исходное расширение файла с помощью file.mimetype

попробуйте console.log(file.mimetype), вы получите имя и расширение файла, разделенные символом "/", а затем я разделил его на массив и извлек из него расширение. Попробуйте приведенный ниже код.

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

Ответ 4

попробуйте этот способ, который я использую

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

Ответ 5

Лично я реализовал следующие решения, которые генерируют случайное имя для файлов и добавляет исходное расширение файла (я предполагаю, что мое расширение после последнего.)

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

    */
    });


В документации MULTER вы найдете следующее:

Механизм дискового хранилища дает вам полный контроль над хранением файлов в диск.

Доступны два варианта: назначение и имя_файла. Они есть обе функции, определяющие, где должен храниться файл.

Примечание.. Вы несете ответственность за создание каталога при предоставлении назначение как функция. При передаче строки, multer будет убедитесь, что каталог создан для вас.

filename используется для определения того, какой файл должен быть назван внутри папка. Если имя файла не указано, каждому файлу будет присвоено случайное имя который не включает расширение файла.

Примечание. Multer не добавит вам расширение файла, ваша функция должен возвращать имя файла с расширением файла.

Ответ 6

У файла есть такая структура:

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

}

Следующий пример сохраняет файл с оригинальным именем расширения, а не со странным именем, как это по умолчанию. (Вместо "file.originalname" вы можете сохранить его, как хотите)

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