问题
I'm using multipart/form-data in my NodeJS project which lets the user upload a MP3 and set the settings.
I decided to use multer middleware which works fine. https://github.com/expressjs/multer
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('/');
});
}
});
The problem req.body.gender returns always undefined, because I have to use it inside the uploadSong listener.
I want to upload the song when the gender is zero.
回答1:
(A) Not possible with multer.
(B) Use busboy. It uses streams to parse the form data and so you can get form elements values before the file upload and the fields are made available as events.
(C) Another solution (if you prefer using multer) is to use multer but add a header to send the value of the parameter to check before file upload. Headers are available as soon as the request reaches the server.
回答2:
This is my sample code, it is woking fine, if you need further explanation please let me know. hope helpful.
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;
}
回答3:
by using multer form-data parser you can parse form and access req.body
before multer starts just register this app middle-ware:
import * as multer from "multer";
// parse form-data
app.use(multer().any());
来源:https://stackoverflow.com/questions/41663527/how-to-get-the-body-before-uploading-file-in-multer