简体   繁体   English

Node.js 和 Multer - 在回调函数 (req,res) 中处理上传文件的目的地

[英]Node.js and Multer - Handle the destination of the uploaded file in callback function (req,res)

I'm new to Node.js and I ran into a simple problem lately.我是 Node.js 的新手,最近遇到了一个简单的问题。

I'm using multer module to upload images.我正在使用multer模块上传图像。 In my web app all the users have a unique id, and I want the uploaded images to be stored in a directory to be named based on their id.在我的网络应用程序中,所有用户都有一个唯一的 id,我希望上传的图像存储在一个目录中,以根据他们的 id 命名。

Example:例子:

.public/uploads/3454367856437534

Here is a part of my routes.js file:这是我的routes.js文件的一部分:

// load multer to handle image uploads
var multer  = require('multer');
var saveDir = multer({
  dest: './public/uploads/' + req.user._id, //error, we can not access this id from here
  onFileUploadStart: function (file) { 
  return utils.validateImage(file); //validates the image file type
  }
});

module.exports = function(app, passport) {

app.post('/', saveDir, function(req, res) {
                id     : req.user._id,  //here i can access the user id
    });
});

}

How can I access req.user._id attribute outside the callback function(req, res) , so I can use it with multer , to generate the proper directory based on the id?如何在回调function(req, res)之外访问req.user._id属性,以便我可以将它与multer一起multer ,以根据 id 生成正确的目录?

EDIT Here is what I have tried and didn't work:编辑这是我尝试过但没有用的:

module.exports = function(app, passport) {

app.post('/', function(req, res) {
    app.use(multer({
        dest: './public/uploads/' + req.user._id
    }));
});

}

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 DiskStorage to specify where & how of the stored file.您需要使用DiskStorage来指定存储文件的位置方式
  2. By default, multer will use the operating system's default directory.默认情况下,multer 将使用操作系统的默认目录。 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.我们需要确保该文件夹存在,然后才能将文件保存在那里。

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 userId = req.user._id;
      let path = `./public/uploads//${userId}`;
      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('/', upload.single('file'), (req, res) => {
  res.status(200).send();
});

fs-extra for creating directory, just in case 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('/', multer({
dest: './public/uploads/',
changeDest: function(dest, req, res) {
    var newDestination = dest + req.user._id;
    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
});

you can solve this just referring to the input name and rename the path before assigning it.您可以仅参考输入名称并在分配之前重命名路径来解决此问题。

app.use(multer({ dest: './standard_folder/',
    rename: function (fieldname, filename) {

      var pathHelper ='';
      if(fieldname =='otherKindOfFolderNeeded'){
        pathHelper = '../../path/to/other/folder/';
      }
      return pathHelper+uuid.v4()+Date.now();
    },
    onFileUploadStart: function (file) {
      console.log(file.originalname + ' is starting ...')
    },
    onFileUploadComplete: function (file) {
      console.log(file.fieldname + ' uploaded to  ' + file.path)
      done=true;
    }
  })
);

You can accomplish this using multer to handle the dynamic creation of upload directory.您可以使用 multer 来处理上传目录的动态创建。 The input parameter(for which you want to create a directory) should be called before sending a file name.应该在发送文件名之前调用输入参数(您要为其创建目录)。

var express = require('express');
var app = express();
var multer = require('multer');
var fs = require('fs');
var mkdirp = require('mkdirp');
var bodyParser = require('body-parser');
app.use(bodyParser.json({limit: '5mb'}));
app.use( bodyParser.json() );       // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({     // to support URL-encoded bodies
    extended: true,
    limit: '5mb'
}));

var storage =   multer.diskStorage({
    destination: function (req, file, callback) {
        var Id = req.body.id;
        upload_path = "./"+Id;
        mkdirp(upload_path, function (err) {
            if (err) console.error(err)
            else {
                console.log('Directory created');
                //setting destination.
                callback(null, upload_path);
            }
        });

    },
    filename: function (req, file, callback) {
        callback(null, file.orginalname)
    }
});
//multer setting and getting paramaters.
var upload = multer({ storage : storage }).single('upload_file');

//creating request for upload file
app.post('/uploadFile', function(req, res){
    res.set({ 'content-type': 'application/json; charset=utf-8' });
    res.header("Content-Type", "application/json; charset=utf-8");
    res.header("Access-Control-Allow-Origin", "*");
    res.charset = 'utf-8';
    //function upload_process(){
    upload(req, res, function(err){
        if(err){
            console.log('Error-->');
            console.log(err);
            res.json({"status": "Failure", "message":'There was a problem uploading your files.'+err});
            return;
        }
        else{
            console.log("fieldname"+req.files.length);
            if( req.files.length != 0){
                res.json({"status" : "Success", "message":'Your files are uploaded.'});
                console.log('File uploaded!');
            }
            else{
                console.log("No file uploaded. Ensure file is uploaded.");
                res.json({"status" : "Failure", "message" : 'No file uploaded. Ensure file is uploaded.'});

            }
        }
    });

});

});

Hope this helps!希望这可以帮助! Happy coding快乐编码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM