Express body-parser req.body with formdata is empty object - javascript

Somehow my req.body is always empty, maybe you have an idea:
here is my server code:
const Express = require('express');
const bodyParser = require('body-parser');
const app = new Express();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.post('/save', (req, res) => {
console.log(req.body) // => {}
res.send(req.body);
});
const env = process.env.NODE_ENV || 'production';
app.listen(3000, err => {
if (err) { return console.error(err); }
console.info(`Server running on http://localhost:${port} [${env}]`);
});
When I try to send formdata with javascript the req.body is empty:
const data = new FormData(document.querySelector('form'));
console.log(data); // seems empty already??? FormData{}??
const xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost:3000/save');
xhr.send(data);
Same with postman:
I don’t understand this…
Sending x-www-form-urlencoded with postman or raw (application/json) works in postman. But sending the same headers with Formdata in javascript will still result in an empty object…

To log every field in formData
let myForm = document.getElementById('myForm');
formData = new FormData(myForm);
for (let [key, value] of formData.entries()) {
console.log(key, value);
}
Fiddle - https://jsfiddle.net/thesumit67/j4znhxa5/1/
To handle it via express use multer.
Here is an example -
https://www.npmjs.com/package/multer
Make sure to add enctype="multipart/form-data" on form element. Otherwise Multer will ignore it.
let multer = require('multer');
let upload = multer();
app.post('/save', upload.fields([]), (req, res) => {
console.log( req.body );
console.log( req.files );
res.sendStatus(200);
});

body-parser is deprecated and isn't a part of Express anymore.
Also, body-parser does not provide the functionality to parse form-data post data.
From the body-parser repository description:
This does not handle multipart bodies, due to their complex and typically large nature. For multipart bodies, you may be interested in the following modules:
busboy and
connect-busboy
multiparty and
connect-multiparty
formidable
multer

From what I understand, the problem may be in the HTML form.
<form action="" method="POST">
<input type="text" name="foo[bar]">
<button>Submit</button>
</form>
Then in the server code it may look something like this.
app.post('/save', (req, res) => {
console.log(req.body.foo) // => {}
res.send(req.body.foo);
});
Again, this post is older so you've probably already fixed it.

I had this same problem, I was using the fetch api, sending form data to an node.js/express backend. The problem was that I had set enctype='multipart/form-data' on the form and I was also setting Content-type: multipart/form-data in the fetch Headers.
Removing the Content-type from the Headers got everything to work.
I got the solution from here => https://github.com/expressjs/multer/issues/411

Express and body parser Version :
"dependencies": {
"body-parser": "^1.19.0",
"express": "^4.17.1"
}
app.js:
const express = require('express');
var bodyParser = require('body-parser')
const app = express();
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
app.use( bodyParser.json());
const baseUrl = '/api/v1/tours';
app.post(baseUrl, (req, res)=>{
console.log(req.body);
res.send('Done');
})
//starting server
const port = 3000;
app.listen(port, ()=>{
console.log(`app running on port ${port}...`);
});
To send raw data please select JSON from the list

Related

express.js get method cannot get req.body value

I use vue3, vuex, express.js and mysql. In the below router get method, I call "console.log(req.body)" and shows "[object Object]", and I call "console.log(req.body.userid)" and shows "undefined".
router.get('/',async function(req,res){
const userId = req.body.userid;
console.log("req body is: "+req.body);
console.log("req.body.userid is: "+req.body.userid);
.....
}
In the below method, I pass userid value as a json object. I call "console.log("post userid: "+userinfo.userid);" and shows the the right value "1";
async getsp(){
var userinfo = JSON.parse(localStorage.getItem('user'));
console.log("post userid: "+userinfo.userid);
var userid = userinfo.userid;
var obj = {userid};
return await axios.get('//localhost:8081/getSp',obj)
.then(...)
},
And in the main router file I used body-parser, the file context is below:
require("dotenv").config();
const express = require('express');
const bodyParser = require('body-parser');
var cors = require('cors');
const signup = require('./userSignUp');
const login = require('./userLogin');
const createEvsp = require('./createEvsp');
const getSp = require('./getSp');
//const createFile = require('./createFile');
const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json())
app.use(cors())
app.use(express.json());
app.use(
express.urlencoded({
extended: true
})
);
app.use("/signup",signup);
app.use("/dologin",login);
app.use("/createEvsp",createEvsp);
app.use("/getSp",getSp);
//app.use("/createFile",createFile);
app.listen(8081,function () {
console.log('Server running at 8081 port');
});
The problem was an HTTP method understanding and how express works
To solve it it was needed to use the express middleware /:userid for accessing to the parameter using req.params.userid
According to the http standards for sending the data we generally use POST request.
There is a good answer in stack here Information about Get HTTP Request
Sayf-Eddine

Post request body empty - XMLHttpRequest to Express server

I am trying to access a body from a post request sent using XMLHttpRequest to an express server. However the body of the request is empty and I cannot seem to understand why that is.
I have included a body-parser in the express app, and I have tried to replicate some code from SO answers. But I still get it wrong somehow.
<script>
const Http = new XMLHttpRequest();
Http.open('post', 'localhost:3000');
Http.send("sending something!");// this resolves to {} on the backend?
Http.onload = function() {
alert(Http.response);
};
</script>
This is how I try to handle it on my express server
const express = require("express");
let app = express()
const bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({
extended: true
}));
app.post("/post", (req, res) => {
console.log("inside of post");
console.log(req.body);
})
app.listen(3000)
This is the logs
inside of post
{}
I expect the console.log() to print "sending something!" that I try to send with the request with Http.send("sending something!");.
You have specified the body-parser to parse the body as url-encoded format which would work if you pass data like this:
Http.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
Http.send("param1=value1&param2=value2");
/* console output:
{ param1: 'value1', param2: 'value2' }
*/
In your case, the data being passed is simple string, which the backend interprets as empty JSON {} as it is unable to parse.
For it to work try setting the format of data as follows
<script>
const Http = new XMLHttpRequest();
Http.open('post', 'localhost:3000');
Http.setRequestHeader("Content-Type", "text/plain");
Http.send("sending something!");
Http.onload = function() {
alert(Http.response);
};
</script>
And in express server:
const express = require("express");
let app = express();
const bodyParser = require("body-parser");
// app.use(
// bodyParser.urlencoded({
// extended: true
// })
// );
app.use(bodyParser.text({ type: "text/plain" })); // use this instead
app.post("/post", (req, res) => {
console.log("inside of post");
console.log(req.body);
return req.body;
});
app.listen(3000);
Then you might be able to read the message "sending something!" in the backend.
Just make sure you are setting the right contentType header in XMLHttpRequest while sending and you use same type while parsing in the backend as well.
For more info on bodyParsers refer this doc

Javascript express mongodb server not getting data from post request

I am trying to set up a very simple javascript server however I cant even properly get the data from a post request!
Here is what I am doing. I have annotated what works and what doesn't. Essentially everything except for the post request works perfectly. Unfortunately the body of the request is always empty resulting in garbage information.
const MongoClient = require('mongodb').MongoClient;
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({ extended: false }))
const mongoUrl = '<DBAddress Goes Here>';
MongoClient.connect(mongoUrl, (err, mongoDb) => {
if(!err) {
db = mongoDb;
console.log("Connected correctly to server");//This always happen successfully
}
});
app.listen(80);
app.get('/test', function(req, res) {
res.json({ data1: 11, data2: 4, data3: 9 }); //This always works!
});
app.post('/update', function(req, res) {
const params = req.body;
console.log(req.body);//Empty
console.log("Parameters");
const newReport = {
id: params.id,
data: params.data
};
console.log(newReport);//Nothing is put in here
});
I am testing this post request in Postman with website.com/update as the address and the proper fields in the body part of the post.
You need to parse request body in order to get the body in req.body.
As you are already using body-parser package just add the following line after your urlEncoded middleware. and remember the order of middleware matters in the express.
app.use(bodyParser.json());
add above line right after this
app.use(bodyParser.urlencoded({ extended: false }))
And make sure that you are sending data in the JSON format as by default postman send data in plain format

Graphql: Must provide query string

I have a simple express graphql server:
const schema = require('./schema');
const express = require('express');
const graphqlHTTP = require('express-graphql');
const cors = require('cors')
const bodyParser = require('body-parser');
const app = express();
app.use(cors());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use('/graphql', graphqlHTTP(req => {
return ({
schema,
pretty: true,
})
}));
const server = app.listen(9000, err => {
if (err) { return err; }
console.log(`GraphQL server running on http://localhost:${9000}/graphql`);
});
And my request looks like:
Any help?
(Please don't close it as duplicate because the other post does not provide enough info on how the user solved it)
You need to specify application/json in your Content-Type header -- you currently have text/plain. You've included the body parser middleware on the server, but it relies on that header in your request to know when it needs to actually parse the response into JSON.

How do I send a file from postman to node.js with multer

Windows
Express 4.12.4
Multer 1.0.1
Node v0.10.22
I'm trying to send a file to my node.js server using postman.
I'm attempting to follow the readme here
Here's what I'm sending with postman:
POST /ingest HTTP/1.1
Host: localhost:3000
Cache-Control: no-cache
Postman-Token: 69dd2497-2002-56ed-30a4-d662f77dc0b0
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Here's what it looks like:
Here's what it's hitting on node.js
var Ingest = require('../controllers/ingest.js');
var multer = require('multer');
var upload = multer({ dest: 'uploads/',fileFilter:function(req,file,cb){
console.log('file is',file)
cb(null,true);
}
});
module.exports = function (app) {
app.post('/ingest', upload.single('test'), function(req, res, next) {
console.log(req.body);
console.log(req.file);
Ingest.ingestData()
.then(function (response){
return res.status(200).json(response);
});
});
}
When I hit this route with postman I get {} for req.body and undefined for req.file.
What am I doing wrong?
Here's where I initialize the app that gets passed in to the route file:
var express = require('express');
var app = express();
var http = require('http');
var cfg = require('./config')();
var passport = require('passport');
var cors = require('cors');
var bodyParser = require('body-parser');
app.set('port', process.env.PORT || cfg.port);
var corsOptions = {
origin: "*",
allowedHeaders: ['Content-Type', 'Authorization', 'Accept', 'x-reset-token', 'x-invite-token', 'x-api-key', 'x-www-form-urlencoded'],
credentials: true
};
app.use(cors(corsOptions));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(passport.initialize());
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
Maybe something in there is doing it?
Edit:
I've even tried
var Ingest = require('../controllers/ingest.js');
var multer = require('multer');
var upload = multer({ dest: 'uploads/',fileFilter:function(req,file,cb){
console.log('file is',file)
cb(null,true);
}
}).single('csv');
module.exports = function (app) {
app.post('/ingest', function(req,res){
upload(req, res, function(err) {
if(err){
console.log(err);
}
console.log(req.body);
console.log(req.file);
Ingest.ingestData()
.then(function (response){
return res.status(200).json(response);
});
});
});
}
And that didn't help. It doesn't log anything for err
Just remove header Content-Type:application/x-www-form-urlencoded from the postman.
In Postman screenshot, the file field name is missing. The key should be csv since Multer accepts single file with that name.
This would help others like me who are searching for a similar answer.
I used a curl request instead of Postman.
curl -v -F csv=#file.csv http://localhost/url
There seems to be an issue with Postman.
https://github.com/expressjs/multer/issues/317
I also have this issue when I use Postman to send file using form-data. The attribute req.file or req.files is always undefined. If anyone has used Postman and was able to retrieve the file using req.file or req.files, please comment.
Updating from Postman version 5.5.3 to version 8.0.7. solved the issue for me. Maybe related to this problem fixed in version 7.
Multer looks for the file named 'single'. So if you add the key as 'single' in postman form-data it should work

Categories

Resources