Как установить различные направления в nodejs с помощью multer?

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

var express = require('express'),
    app = express(),
    multer = require('multer');
app.configure(function () {
    app.use(multer({
        dest: './static/uploads/',
        rename: function (fieldname, filename) {
            return filename.replace(/W+/g, '-').toLowerCase();
        }
    }));
    app.use(express.static(__dirname + '/static'));
});

app.post('/api/upload', function (req, res) {
    res.send({image: true, file: req.files.userFile.originalname, savedAs: req.files.userFile.name});
});

var server = app.listen(3000, function () {
    console.log('listening on port %d', server.address().port);
});

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

var express = require('express'),
    app = express(),
    multer = require('multer');
app.configure(function () {
    app.use(multer({
        //dest: './static/uploads/',
        rename: function (fieldname, filename) {
            return filename.replace(/W+/g, '-').toLowerCase();
        }
    }));
    app.use(express.static(__dirname + '/static'));
});

app.post('/api/pdf', function (req, res) {
    app.use(multer({ dest: './static/pdf/'}));
    res.send({image: true, file: req.files.userFile.originalname, savedAs: req.files.userFile.name});
});

app.post('/api/image', function (req, res) {
    app.use(multer({ dest: './static/image/'}));
    res.send({image: true, file: req.files.userFile.originalname, savedAs: req.files.userFile.name});
});

app.post('/api/video', function (req, res) {
    app.use(multer({ dest: './static/video/'}));
    res.send({image: true, file: req.files.userFile.originalname, savedAs: req.files.userFile.name});
});

var server = app.listen(3000, function () {
    console.log('listening on port %d', server.address().port);
});

означает, если я нажму http://localhost:3000/api/pdf файл должен храниться в папке "pdf", если я нажму http://localhost:3000/api/video файл должен храниться в папке "Видео".

есть ли способ достичь этого цель?

спасибо заранее.

5 ответов


обновление

довольно много вещей изменилось с тех пор, как я опубликовал оригинальный ответ.

С multer 1.2.1.

  1. вам нужно использовать DiskStorage указать здесь & как сохраненного файла.
  2. по умолчанию multer будет использовать каталог операционной системы по умолчанию. В нашем случае, так как мы разбираемся в местоположении. Нам нужно убедиться, что папка существует, прежде чем мы сможем сохранить файл вон там.

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

больше здесь

'use strict';

let multer = require('multer');
let fs = require('fs-extra');

let upload = multer({
  storage: multer.diskStorage({
    destination: (req, file, callback) => {
      let type = req.params.type;
      let path = `./uploads/${type}`;
      fs.mkdirsSync(path);
      callback(null, path);
    },
    filename: (req, file, callback) => {
      //originalname is the uploaded file's name with extn
      callback(null, file.originalname);
    }
  })
});

app.post('/api/:type', upload.single('file'), (req, res) => {
  res.status(200).send();
});

fs-extra для создания каталога, на всякий случай, если он не существует

оригинальный ответ

можно использовать changeDest.

функция для переименования каталога, в котором для размещения загруженных файлов.

Он работает с версия v0.1.8

app.post('/api/:type', multer({
dest: './uploads/',
changeDest: function(dest, req, res) {
    var newDestination = dest + req.params.type;
    var stat = null;
    try {
        stat = fs.statSync(newDestination);
    } catch (err) {
        fs.mkdirSync(newDestination);
    }
    if (stat && !stat.isDirectory()) {
        throw new Error('Directory cannot be created because an inode of a different type exists at "' + dest + '"');
    }
    return newDestination
}
}), function(req, res) {
     //set your response
});

Multer-это промежуточное ПО, поэтому вы можете передать его следующим образом:

app.post('/test/route', multer({...options...}), module.someThing)

или

app.post('/test/route', multer({...options...}), function(req, res){
........some code ......
});

Вы можете сделать функцию вот так:

var uploadFnct = function(dest){
        var storage = multer.diskStorage({ //multers disk storage settings
            destination: function (req, file, cb) {
                cb(null, './public/img/'+dest+'/');
            },
            filename: function (req, file, cb) {
                var datetimestamp = Date.now();
                cb(null, file.fieldname + '-' + datetimestamp + '.' + file.originalname.split('.')[file.originalname.split('.').length -1]);
            }
        });

        var upload = multer({ //multer settings
                        storage: storage
                    }).single('file');

        return upload;
    };

а затем используйте его в своем маршруте загрузки:

//Handle the library upload
    app.post('/app/library/upload', isAuthenticated, function (req, res) {
        var currUpload = uploadFnct('library');
        currUpload(req,res,function(err){
            if(err){
                 res.json({error_code:1,err_desc:err});
                 return;
            }
            res.json({error_code:0,err_desc:null, filename: req.file.filename});
        });
    });

я попробовал решения, показанные здесь, но ничего не помогло мне.

ChangeDest attr больше не доступен (как предлагает Шридхар в своем ответе)

Я хочу поделиться своим решением (я использую express 4.13 и multer 1.2):

импорт:

var express = require('express');
var router = express.Router();
var fs = require('fs');
var multer  = require('multer');


переменной хранения (см. документацию здесь)

var storage = multer.diskStorage({
    destination: function (req, file, cb) {
        var dest = 'uploads/' + req.params.type;
        var stat = null;
        try {
            stat = fs.statSync(dest);
        } catch (err) {
            fs.mkdirSync(dest);
        }
        if (stat && !stat.isDirectory()) {
            throw new Error('Directory cannot be created because an inode of a different type exists at "' + dest + '"');
        }       
        cb(null, dest);
    }
});


инициализация Малтер:

var upload = multer(
    { 
        dest: 'uploads/',
        storage: storage
    }
);


использовать его!

router.use("/api/:type", upload.single("obj"));
router.post('/api/:type', controllers.upload_file);

var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    if (req.path.match('/pdf')) {
      cb(null,<destination>)
    }
  },
  filename: function (req, file, cb) {
  }
})

это работает в случае, если путь уникален. Вы можете изменить (проверка конечной точки {req.путь}) в соответствии с вашими потребностями. Хотя это решение не является динамичным.