I am using Multer to parse a multipart form in a keystone environment and and not able to access the req.body and req.file data inside my route controller
routes/index.js
var keystone = require('keystone'),
middleware = require('./middleware');
var bodyParser = require('body-parser');
//multi-part form parser for FTP api
var multer = require('multer');
var storage = multer.memoryStorage();
var upload = multer({storage: storage});
exports = module.exports = function(app) {
app.use(bodyParser.json({limit: '10mb'}));
app.use(bodyParser.urlencoded({limit: '10mb', extended: true}));
app.post('/upload_api', upload.single('formFile'), routes.api.uploadFTP);
};
routes/api/uploadFTP.js
var keystone = require('keystone');
var ftpMod = require('ftp');
var fs = require('fs');
exports = module.exports = function(req, res) {
console.log("req.body is ");
console.log(req.body);
console.log("req.file is ");
console.log(req.file);
res.send("console.log() outputted to screen");
}
public/test-upload.html
<html>
<body>
<form name="sampleForm" enctype="multipart/form-data" action="/upload_api" method="post">
<p>Method</p>
<input type="text" name="method"><br>
<p>Options</p>
<input type="text" name="options"><br>
<p>File</p>
<input type="file" name="formFile"><br><br>
<input type="submit" value="Click to Send">
</form>
</body>
</html>
The response i receive from nodejs is
>req.body is
{}
req.file is
undefined
I am expecting req.body to contain {method: "sometext"} and req.file to be populated
specifically, I noticed req.file is undefined while using upload.single() but req.files is populated.
This is at odds with the expected behavior according to the documentation
Having same issue with this version in my package.json "multer": "^1.3.0".
All code that i see from Stack Overflow use req.file in conjunction with upload.single().
So something must have change to cause this.
This is what I just discovered for my case.
In server.js I have
app.use(multer({dest:'./public/uploads/'}).any());
while my routes is using uploads.single. This is what caused req.file to be undefined but req.files to be populated.
After correcting the app.use() line in server.js to
app.use(multer({dest:'./public/uploads/'}).single('file'));
It begin to work as expected.
Yeah, that's probably it. The first middleware will consume the request body, and then there will be nothing left in the stream to consume...
@LinusU @HarisHashim Can you please post the correct code here
So, the right way is to use upload.single() ?. I don't now right answer, how to parse both text and file. Help me, thanks.
Hi,
If you are still interested, my issue was that multer was the second middleware and req.file was empty. After moving multer to be the first middleware, everything worked.
I have the same problem, if only the file is uploaded then it uploads smoothly but if the form has a file and some fields then req.body is empty and req.files is undefined but it works using postman though :l
@saadnaseem97 are you using any other body-parsing middleware? How does your request look in postman?
Is there is any way to update multiple image in multer??? My upload code works file.. comes to update i got this error " Cannot read property 'filename' of undefined"
@vigneshkvw how are you reading filename? If you have multiple files you can no longer read req.file.filename, but must instead iterate over the req.files property:
for (const file of req.files) {
console.log(file.filename)
}
@saadnaseem97 can you show how you uploaded file directly without using formdata ?
@marypreethi12 What do you mean by directly? If you plan on using an html form to upload a file, it is best practices to set the method to multipart/form-data. The get and post methods do not support file transfer directly.
It would be possible to use the File API in the browser to convert the the file to base64 string and send this string in a form field with the get or post methods.
See this link for an walkthrough of applicable API.
@vigneshkvw Please help me i am facing the same issue.Did you solve this...?
Yeah, I am still getting this issue. I installed the new bodyparser and multer middleware, but it won't populate req.body in a multipart form. Anyone figure it out?
https://github.com/musmanalibaloch/express-form-data, Use this example, it uses firebase cloud function and firebase storage to upload file but you can use it for anything , it uses express-multipart-file-parser and works like charm the above link just works perfectly,I tested this code and pushed it to repo for you guys.Just add your configuration and there you go.Cheers.
I am also experiencing this for multi file uploads. For some reason a single file works as expected. I have an open question on stackoverflow. My code is nearly identical to the single file upload but the req.files end up empty and can be found in req.body. Here is the question if anyone is interested in helping me with this. I've gone through solutions on this page and everything I could find on stackoverflow.
https://github.com/musmanalibaloch/express-form-data, Use this example, it uses firebase cloud function and firebase storage to upload file but you can use it for anything , it uses express-multipart-file-parser and works like charm the above link just works perfectly,I tested this code and pushed it to repo for you guys.Just add your configuration and there you go.Cheers.
@FrancoTanzarella did you look at it? I had the same issue wasted a lot of time and then after solving shared that on git
@musmanalibaloch - I did try that, although only the parts I thought were relevant.
const { fileParser} = require('express-multipart-file-parser');
app.use(fileParser({
rawBodyOptions: {
limit: '15mb', //file size limit
},
busboyOptions: {
limits: {
fields: 20 //Number text fields allowed
}
},
}))
Am I missing something?
@FrancoTanzarella
After that try something like this with some dummy route
app.post('/v1/image', (req, res) => {
if (req.files) { //check if images array is populated
//access images like req.files[index] where index starts from 0
//req.files[0] first file
//req.files[1] second file ...
})
use data-form to send images to server , you can use postman to test
Using your solution with postman and testing with my existing route, uploads the images successfully with the other data. When I test using my form however, just the form data save but no image uploads and also the req.files is still empty.
@FrancoTanzarella in case of web frontend you need to use
what are using at frontend?
and for side not please give star to my repo so others can get help from it.
@musmanalibaloch I am using react. My code is on the stackoverflow link I posted above.
can you check network tab in browser if data being sent to server? @FrancoTanzarella
@musmanalibaloch - thanks for your help. I managed to fix it. Turns out I was concatenating the FileList object to an array in my state so the structure was all wrong and at the server it just failed silently. My images upload perfectly now.
Awesome, good to hear that you got it solved. 馃憤 @FrancoTanzarella
Most helpful comment
specifically, I noticed
req.fileis undefined while usingupload.single()butreq.filesis populated.This is at odds with the expected behavior according to the documentation