在单独的控制器功能中使用 Multer 文件上传
Use Multer file upload within a separate controller function
我正在编写一个 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()
}
给我 Error: Route.post() requires a callback function but got a [object Promise]
是否可以按照我描述的方式使用multer?谁能指出我可能误解了什么?我是 Node+Express 的新手,所以如果我错过了一些需要的信息,请告诉我。
您提出的函数不符合Express中间件的签名规范。签名必须是:
function(requestObject, responseObject, nextCallback){}
函数的 return 值并不重要(但你 returning 一个 Promise
因为你声明它 async
)。您正在传递一个 Error Middleware,因为您要返回一个带有 4 个参数的函数。
我认为你应该分解逻辑,将请求类型检查到它自己的中间件中,单独链接到 multer,然后在它自己的中间件中进行请求转换,除非我遗漏了什么:
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) => {});
我正在编写一个 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()
}
给我 Error: Route.post() requires a callback function but got a [object Promise]
是否可以按照我描述的方式使用multer?谁能指出我可能误解了什么?我是 Node+Express 的新手,所以如果我错过了一些需要的信息,请告诉我。
您提出的函数不符合Express中间件的签名规范。签名必须是:
function(requestObject, responseObject, nextCallback){}
函数的 return 值并不重要(但你 returning 一个 Promise
因为你声明它 async
)。您正在传递一个 Error Middleware,因为您要返回一个带有 4 个参数的函数。
我认为你应该分解逻辑,将请求类型检查到它自己的中间件中,单独链接到 multer,然后在它自己的中间件中进行请求转换,除非我遗漏了什么:
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) => {});