Javascript 在单独的控制器功能中使用Multer文件上载

Javascript 在单独的控制器功能中使用Multer文件上载,javascript,node.js,express,multer,Javascript,Node.js,Express,Multer,我正在编写一个Express应用程序,为了避免弄乱我的routes.js文件,我创建了一个单独的UploadController,如下所示: // UploadController.js const multer = require('multer') const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, 'public/' + file.fieldname + '/

我正在编写一个Express应用程序,为了避免弄乱我的
routes.js
文件,我创建了一个单独的
UploadController
,如下所示:

// UploadController.js
const multer = require('multer')
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'public/' + file.fieldname + '/')
  },
  filename: function (req, file, cb) {
    cb(null, Date.now() + '-' + file.originalname)
  }
})

const upload = multer({
  storage: storage
})

module.exports = {
  upload
}
我在
routes
中使用它,具体来说,这只是我的注册路线的一个例子:

app.post('/register',
    RegistrationPolicy.validate,
    UploadController.upload.single('avatar'),
    UserController.register)
这个很好用。理想情况下,在上传运行之前,我需要检查请求类型是否为
multipart/form data
,然后在上传完成后,运行:

req.body.avatarUri = req.file.destination + req.file.filename
这样,当运行
UserController.register
时,上载文件的URI将存储在我的数据库中

我能想到的最简洁的方法是在我的控制器中创建一个自定义的
upload
方法,该方法执行检查、上传操作,然后是URI分配。问题是,把Multer放在这样一个函数的中间:

async upload (req, res, next, field) {
    // ...check request type...
    multerUpload.single(field)
    // ...assign URI...
    next()
}
告诉我
错误:Route.post()需要回调函数,但得到了[object Promise]


可以用我描述的方式使用multer吗?有人能指出我的误解吗?我是Node+Express的新手,因此如果我遗漏了一些需要的信息,请告诉我

您提出的函数不符合Express中间件的签名规范。签名必须是:

function(requestObject, responseObject, nextCallback){}
函数的返回值实际上并不重要(但是您正在返回一个
承诺
,因为您声明了它
异步
)。您正在传递,因为您正在返回一个具有4个参数的函数


我认为您应该打破逻辑,在自己的中间件中进行请求类型检查,分别链接到multer,然后在自己的middlware中进行请求转换,除非我遗漏了什么:

function checkMultipart(req, res, next) {
    const contentType = req.headers["content-type"];
    // Make sure it's multipart/form
    if (!contentType || !contentType.includes("multipart/form-data")) {
        // Stop middleware chain and send a status
        return res.sendStatus(500);
    }
    next();
}

function rewriter(req, res, next) {
    // Set the request fields that you want
    req.body.avatarUri = req.file.destination + req.file.filename;
    next();
}

router.post("/", checkMultipart, upload.single("avatar"), rewriter, (req, res, next) => {});

为什么要使用
async
函数?Express中间件模式需要
函数(请求、响应、nextCallback){}
。此外,您提供的函数签名将被视为一个函数签名,因为它有4个参数。你能多看看你的路由器吗?谢谢。这是我曾经尝试过的,但由于某种原因,它没有起作用。我想我只是在某个地方做错了什么事,没有注意到,因为已经很晚了。我将重试此操作,如果再次遇到问题,我将返回。这应该会起作用,这也是解决此问题的方法