如何使用multer在nodejs中设置不同的目的地?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25698176/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 17:52:16  来源:igfitidea点击:

How to set different destinations in nodejs using multer?

node.jsmulter

提问by AkshayP

I'm trying to upload any file using Multer package. It's working fine when I use following code in my server.jsfile.

我正在尝试使用Multer package上传任何文件。当我在我的server.js文件中使用以下代码时,它工作正常。

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

What I want is to store file at different locations. I had tried following code but it does not work for me.

我想要的是将文件存储在不同的位置。我曾尝试以下代码,但它对我不起作用。

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

Means, if I hit http://localhost:3000/api/pdffile should store at 'pdf' folder, if I hit http://localhost:3000/api/videofile should store at 'video' folder.

意思是,如果我点击http://localhost:3000/api/pdf文件应该存储在“pdf”文件夹中,如果我点击http://localhost:3000/api/video文件应该存储在“视频”文件夹中。

Is there any way to achieve this aim?

有没有办法实现这个目标?

Thank you in advance.

先感谢您。

回答by Sridhar

Update

更新

Quite a few things have changed since I posted the original answer.

自从我发布原始答案以来,很多事情都发生了变化。

With multer 1.2.1.

multer 1.2.1.

  1. You need to use DiskStorageto specify where& howof the stored file.
  2. By default, multer will use the operating system's default directory. In our case, since we are particular about the location. We need to ensure that the folder exists before we could save the file over there.
  1. 您需要使用DiskStorage来指定存储文件的位置方式
  2. 默认情况下,multer 将使用操作系统的默认目录。在我们的例子中,因为我们对位置很挑剔。我们需要确保该文件夹存在,然后才能将文件保存在那里。

Note: You are responsible for creating the directory when providing destination as a function.

注意:将目标作为函数提供时,您负责创建目录。

More here

更多在这里

'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-extrafor creating directory, just in case if it doesn't exists

fs-extra用于创建目录,以防万一它不存在

Original answer

原答案

You can use changeDest.

您可以使用changeDest

Function to rename the directory in which to place uploaded files.

重命名放置上传文件的目录的功能。

It is available from v0.1.8

它可以从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
});

回答by munzx

Multer is a middleware so you can pass it like this :

Multer 是一个中间件,因此您可以像这样传递它:

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

or

或者

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

回答by emcee22

You can make a function like so:

您可以创建这样的函数:

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

And then use it in your upload route:

然后在您的上传路线中使用它:

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

回答by Jordy Cuan

I tried the solutions shown here but nothing helped me.

我尝试了此处显示的解决方案,但没有任何帮助。

ChangeDest attr is not available anymore (As Sridhar proposes in his answer)

ChangeDest attr 不再可用(正如 Sridhar 在他的回答中提出的那样)

I want to share my solution (I am using express 4.13 and multer 1.2):

我想分享我的解决方案(我使用的是 express 4.13 和 multer 1.2):

Imports:

进口

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


Storage variable(see documentation here)


存储变量(请参阅此处的文档)

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


Initializing Multer:


初始化 Multer:

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


Using it!


使用它!

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

回答by Aditya

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

This works in case, the path is unique. You can modify (checking for the end point {req.path}) according to your needs. Though this solution is not dynamic.

这在路径是唯一的情况下有效。您可以根据需要进行修改(检查终点 {req.path})。虽然这个解决方案不是动态的。