在我的项目中,管理员能够上传 MP3 文件并向其提交参数(例如歌曲名称)。
我决定使用 multer 中间件来处理
multipart/form-data
。
我的问题是
req.body.gender
返回始终未定义,因为我必须在 uploadSong
侦听器中使用它。我想在性别为零时上传歌曲。
index.ejs
<form method="post" action="/acp" role="publish" enctype="multipart/form-data">
<div class="form-group">
<input type="file" name="song" id="song" accept="audio/mpeg">
</div>
<input type="checkbox" name="gender" checked data-toggle="toggle" data-on="Male" data-off="Female">
</form>
app.js
var uploadSong = upload.single('song');
app.post('/acp', isLoggedIn, function (req, res) {
console.log(req.body.gender); // returns "undefined"
if(req.body.gender == 0) { // returns "undefined"
uploadSong(req, res, function (err) {
if (err) {
res.send('uploaded');
return;
}
res.redirect('/');
});
}
});
(A) multer 不可能。
(B) 使用busboy。它使用流来解析表单数据,因此您可以在文件上传之前获取表单元素值,并且字段可作为事件使用。
(C) 另一种解决方案(如果您更喜欢使用 multer)是使用 multer 但添加标头以发送参数值以在文件上传之前进行检查。请求到达服务器后,标头就可用。
通过使用 multer form-data 解析器,您可以在 multer 启动之前解析表单并访问
req.body
,只需注册此应用程序中间件即可:
import * as multer from "multer";
// parse form-data
app.use(multer().any());
这是我的示例代码,运行良好,如果您需要进一步的解释,请告诉我。希望有帮助。
var Hotel = require('../models/hotel');
var path = require('path');
var multer = require('multer');
var uplodedImages = [];
var storageHotelGallery = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads/hotelGallery');
},
filename: function (req, file, cb) {
console.log(req.body);
var newFileName = Date.now() + path.extname(file.originalname);
req.newFileName = newFileName;
cb(null, newFileName);
uplodedImages.push(newFileName);
}
});
var uploadHotelGallery = multer({ storage: storageHotelGallery}).fields([{ name: 'imgArr', maxCount: 8 }]);
module.exports = function(router) {
// ADD HOTEL BASIC DATA TO CREATE HOTEL OBJECT
router.post('/createHotelStep1', function(req, res) {
if( req.body.name == null || req.body.name == '' ) {
res.json({ success: false, message: "Hotel name required" });
res.end();
}
else if( req.body.addressline1 == null || req.body.addressline1 == '' ) {
res.json({ success: false, message: "Address line 1 is required" });
res.end();
}
else if( req.body.city == null || req.body.city == '') {
res.json({ success: false, message: "City is required" });
res.end();
}
else {
var hotel = new Hotel();
hotel.name = req.body.name;
hotel.addressline1 = req.body.addressline1;
hotel.addressline2 = req.body.addressline2;
hotel.phone = req.body.phone;
hotel.city = req.body.city;
hotel.email = req.body.email;
hotel.save(function(err) {
if (err) {
res.json({ success: false, message: "Unable to Complete Hotel Step 1" });
} else {
res.json({ success: true, message: 'Create Hotel Step 1 Complete', _id : hotel._id });
}
});
}
});
router.post('/createHotelGallery', function (req, res, next) {
uplodedImages = [];
uploadHotelGallery(req, res, function(err) {
if(err) {
res.json({ success: false, message: 'Could not upload images'});
res.end();
}
else {
Hotel.findOne({ _id:req.body._id }).populate('users').exec(function (err, hotel) {
if (err) {
res.json({ success: false, message: 'Could not save uploaded images to database'});
res.end();
}
else {
for(var x=0; x<uplodedImages.length; x++)
hotel.images.push(uplodedImages[x]);
hotel.save();
res.json({ success: true, message: 'Gallery image uploaded' });
res.end();
}
});
}
});
});
return router;
}
这是我的示例代码,运行良好
const upload = multer({
storage,
fileFilter(req, file, cb) {
if(req.body.name===''){
return cb(new Error('Invalid name'), false)
}
const extname = path.extname(file.originalname).toLowerCase() === '.gz'
const mimetype = file.mimetype === 'application/x-gzip'
if (mimetype && extname) {
return cb(null, true)
} else {
return cb(new Error('Invalid mime type'), false)
}
},
})
使用 api 端点作为查询参数发送。它将在图像之前收到。 😊