【问题标题】:How to set different destinations in nodejs using multer?如何使用 multer 在 nodejs 中设置不同的目的地?
【发布时间】:2014-10-31 03:11:45
【问题描述】:

我正在尝试使用 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);
});

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

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,文件应该存储在'video'文件夹中。

有什么办法可以达到这个目的吗?

提前谢谢你。

【问题讨论】:

标签: node.js multer


【解决方案1】:

更新

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

multer 1.2.1

  1. 您需要使用DiskStorage 指定存储文件的位置 & 方式
  2. 默认情况下,multer 将使用操作系统的默认目录。在我们的例子中,因为我们特别关注位置。我们需要确保该文件夹存在,然后才能将文件保存到那里。

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

更多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-extra 用于创建目录,just in case if it doesn't exists

原答案

您可以使用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
});

【讨论】:

  • 有什么方法可以添加日期吗??
【解决方案2】:

Multer 是一个中间件,所以你可以像这样传递它:

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

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

【讨论】:

    【解决方案3】:

    你可以这样写一个函数:

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

    【讨论】:

    • 在提供destination 作为函数时,您负责创建目录。传递字符串时,multer 将确保为您创建目录。
    【解决方案4】:

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

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

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

    进口

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


    存储变量(参见文档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);
        }
    });
    


    初始化 Multer:

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


    使用它!

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

    【讨论】:

      【解决方案5】:
      var storage = multer.diskStorage({
        destination: function (req, file, cb) {
          if (req.path.match('/pdf')) {
            cb(null,<destination>)
          }
        },
        filename: function (req, file, cb) {
        }
      })
      

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

      【讨论】:

        【解决方案6】:

        我们可以得到路径

         const basePath=`${req.protocol}://${req.get("host")}/public/uploads/`;
        

        【讨论】:

          猜你喜欢
          • 2017-12-15
          • 1970-01-01
          • 2020-05-31
          • 1970-01-01
          • 2019-02-09
          • 1970-01-01
          • 1970-01-01
          • 2015-11-06
          • 1970-01-01
          相关资源
          最近更新 更多