ExpressJS request body is empty if i don't use multer - javascript

I have this very strange issue with my express app, i simply want to access req.body data that are send through post request via form-data but unfortunately i get undefined error when i try to access those values in request.body but what is strange about this is if i use multer middleware (i used this on another route to upload files) i don't get this error.
i have configured default body parser provided by express.
//body pharser
app.use(express.json());
app.use(
express.urlencoded({
extended: true,
})
);
//multer configuration
const ImageUpload = multer({
storage: storage,
limits: { fileSize: 4194304 },
fileFilter: Imagfilter,
});
//this will return undefined
app.post("/available",(req, res) => {
console.log(req.body.name);
}
//but this will return the value without any issues
app.post(
"/available",
ImageUpload.fields([
{ name: "nicImageFront", maxCount: 1 },
{ name: "nicImageBack", maxCount: 1 },
]),
(req, res) => {
console.log(req.body.name);
}

There's nothing strange about that.
FormData objects generate multipart requests. They have to, it is how they support file uploads.
The FormData interface provides a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using the XMLHttpRequest.send() method. It uses the same format a form would use if the encoding type were set to "multipart/form-data".
Multer is designed to parse multipart requests.
The urlencoded middleware is designed to parse urlencoded requests, not multipart requests.
The json middleware is designed to parse JSON encoded requests, not multipart requests.

Related

node server cannot find the data in the body

i am sending a post request from fetch but the nodejs server is not able to access the body from the post request. I tried req.body but it just returns empty brackets.
const express = require('express');
const bodyParser=require("body-parser");
const app = express();
app.use(bodyParser.urlencoded({ extended: true}))
app.use(bodyParser.json());
app.use(express.json());
app.get("/user",function(req,res){
res.send("just Checking");
});
app.post("/user", (req, res) => {
console.log(req.body);
res.send("got the data");
});
app.listen(3000,function(res){
console.log("server is workig a t local host 3000");
});
This is the browser side code
const checking = { name:"badmintion" }
function yo (){
fetch("/user",{
method : "POST",
Headers : {
'Content-Type':'application/json'
},
body: JSON.stringify(checking)
})
}
yo();
In the browser i can see that the data is being sent but i am unable to recieve the in the nodejs server it just shows empty brackets.
Edit: I was able to recreate the server code locally on my machine. I didn't find any issues. I used Postman to send the JSON to the /user route. The issue you might be having is in the front end.
Headers should be lowercase. You have capitalized it:
...
fetch("/user",{
method : "POST",
headers : {
...
}
...
Make sure you're sending data in a JSON format so that express can parse it into object:
To avoid any conflict for (parse json) better that remove body parser completely and try again.
For request, according to stanley, headers set as lowercase. Its will be work.
This tutorial maybe help u:
https://www.geeksforgeeks.org/express-js-express-json-function/amp/

Express : Body undefined with post method

I'm trying to get data from a post request using express. But when I use Postman to create the resquest, the req.body is empty (console.log shows 'req {}')
I tried a couple of things and read similar questions in StackOverflow but I couldn't solve my issue.
Here are two screens of my Postman request using form-data and raw :
postman request
postman form
For the second, I also tried with the default content-type before adding application/json
Thanks for your help !
// File : router.js
import express from 'express'
const router = express.Router()
// I tried some router.get routes here and it works with no problem...
router.post('/myurl', (req, res) => {
console.log('req', req.body)
})
export default router
// File : app.js
import express from 'express';
import router from './router.js';
const app = express();
const port = 3000;
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.use('/', router)
app.listen(port, () => {
console.log(`App listening at http://localhost:${port}`);
}
);
You need three elements of the request and server side code to match.
The Content-Type request header must specific the format you are sending the data in
The request body must be encoded to match that header (and be valid)
The server needs body parsing middleware that supports that format.
Your first screenshot shows you are POSTing raw data which is invalid JSON. It does not show what Content-Type request header you are including.
You need to make the JSON valid and ensure that you have Content-Type: application/json in the request headers.
Your second screenshot shows that you are posting multipart/form-data, but you only have middleware that parses application/json and application/x-www-form-urlencoded data.
Either change the format you are POSTing in, or add suitable middleware.
Note also that the Content-Type of the individual parts is wrong. example is not valid JSON (100 is valid JSON but you probably don't want it to be treated as such).

The simplest possible req.body is always empty

I'm just trying to pass the simplest data possible (at the moment, for test purposes) from client to server with a POST request, but I keep getting empty or undefined logs on req.body.
Server:
//jshint esversion:6
const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const app = express();
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static("public"));
mongoose.connect("mongodb://localhost:27017/sandbox", {useNewUrlParser: true});
app.get("/", function(req, res){
res.render("home", {});
})
app.post("/filter", function(req, res){
console.log(req.body);
res.redirect("/");
})
app.listen(3000, function() {
console.log("Server started on port 3000");
});
Client (version 1):
var yourdata = { "name": "The pertinent data"};
console.log(document.body)
$.ajax({
url : "/filter",
type: "POST",
dataType:'text',
data : yourdata,
contentType: "application/json",
});
Client (version 2):
var payload = {data: "The pertinent data"};
var req = new XMLHttpRequest();
req.open('POST', '/filter' , true);
req.send(JSON.stringify(payload))
I added both attempts at a code client-side, but I'm happy with whichever method works. Ideally I'll eventually tap into the payload or data with req.body.payload or something, but at the moment that's just giving me an undefined.
I've looked into quite a few similar posts and usually they were missing the "app.use(bodyParser.urlencoded({extended: true}));" or "app.use(bodyParser.json());" I've tried adding and removing those, changing from true to false, still empty.
The console.log(document.body) on the client script does work, giving me the expected body on the browser console, and the server route is working too, eventually redirecting to home.
I can't see how the issue is something I'm doing wrong on the client side, but oddly enough, if I create a form, with an action to that route, and submit, it seems to send the req.body normally. E.g.:
<form class="form" action="/filter" method="post">
<input name="newName" placeholder="Name">
<button type="submit">Submit</button>
</form>
That does indeed log a JSON object e.g.: { newName: 'John'}
In case it might be relevant, the HTML is the simplest one possible, almost empty, only really doing the pertinent links.
Thanks all in advance!
You need three things:
A request body encoded in some data format
A content-type request header which says which data format you are using
Body parsing middleware that can process that data format
When you submit a form, with no enctype attribute, it will submit the data in URL encoded format with the right content type. This matches the body parsing middleware you have (bodyParser.urlencoded({extended: true})).
1, 2, and 3 are all good.
Note that it does not create a JSON object. The client produces URL encoded data. The server parses that into a JavaScript object. There is no JSON.
Client (version 1):
Here you are passing an object to jQuery so it will URL encode the data in it and would normally set the correct content type.
It is failing because you have contentType: "application/json",.
Since you are falsely claiming that you are sending JSON, bodyParser.urlencoded ignores it.
If you had a JSON body parser in place, it would error because the data is not JSON.
1 and 3 are good, but 2 is a lie.
Remove the contentType property.
Client (version 2):
Now you are JSON encoding the data, but you aren't setting the content type request header, and you don't have body parsing middleware that can handle JSON.
3 is bad, and either 1 or 2 is too.
For the server-side part of your application, you need something that moves the body of the request out of the request string itself to a clear, easy-to-read, and use variable. The express json() method (middleware) does that exactly.
Use the express JSON parser middleware as follows:
app.use(express.json())
Code:
const express = require("express");
// const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const app = express();
app.use(express.json()); // 👈 here
// ... the rest of your code
Just few notes about the middleware you're using
app.use(bodyParser.urlencoded({extended: true}));
We usually use this middleware to parse the HTML forms data, in other words, it's just like the express middleware express.json(), but the difference here is that it parses the requests which have the content type of HTML forms, while the express.json() converts the ones which have the content-type of application/json.
If you're using express v +4, you don't need the bodyParser package, express has the .urlencoded() and the .json() methods built into the express package itself, you can use them just as express.json() and express.urlencoded().
Tip, you can have both middlewares, the JSON parser, and the HTML form content type parser, when the server receives a content-type JSON, the express.json() middleware will parse the request body, and if the server receives an HTML form content-type the urlencoded middleware will fire:
code example:
const express = require("express");
// const bodyParser = require("body-parser"); ❌ not needed
const mongoose = require("mongoose");
const app = express();
app.use(express.json()); // 👈 here
app.use(express.urlencoded({ extended: true })) // 👈 here
// ... the rest of your code

How to read/parse Array in form-data node js

Please check the above image, I am trying to read this in Node Js. I am using express js and have tried debugging req.body. It is returning an empty object {}.
I am using app.use(bodyParser.json({ extended: true })); . To read body but unable to read the data.
I can parse/read json object which are sent in raw(json) format
Edit:
Added multer
But Still Return empty object {}
router.post('/array', uploads.none(), (req, res, next) => {
console.log(req.body)
})
bodyParser.json is used to parse application/json content type. The solution is to use multer middleware to parse form-data content type.
https://www.npmjs.com/package/multer

Express: PayloadTooLargeError: request entity too large

I'm getting this error when I try to send a Base64 string in a POST request.
POST /saveImage 413 10.564 ms - 1459
PayloadTooLargeError: request entity too large
Already tried
--> app.use(bodyParser.urlencoded({ limit: "50mb", extended: true, parameterLimit: 50000 }))
--> app.use(bodyParser.urlencoded({limit: '50mb'}));
--> app.use(bodyParser({limit: '50mb'}));
Here's my code (api.js class)
const express = require('express');
var app = express();
const router = express.Router();
var Connection = require('tedious').Connection
var Request = require('tedious').Request
var TYPES = require('tedious').TYPES
var multer = require('multer');
....
....
....
router.post('/saveImage', (req, res) => {
request=new Request('SAVE_IMAGE',(err, rowCount, rows)=>{
if(err){
console.log(err);
}
});
request.addParameter("Base64Image", TYPES.Text, req.body.IMG)
connection.callProcedure(request);
});
API CALL (Image class contains a Base64 format image and other fields, but I guess the problem occurs because of the Base64 string length. Small images don't cause any trouble)
create(image: Image) {
return this._http.post('/saveImage', image)
.map(data => data.json()).toPromise()
}
I was having the same error. I tried what you tried it did not work.
I guess you are uploading a file. The simple way to solve this is to not set a Content-Type.
my problem was that I was setting on my headers: Content-Type: application/json and I am [was] using multer (expressjs middle for uploading files).
I have the error whenever I try uploading a file.
So when using postman or making such requests using any tools or libraries like axiosjs or fetch() API do not set content-type.
Once you remove the Content-type it will work. That is what I did
on my code, I have:
const express = require('express');
...
const app = express();
app.use(express.json());
...
...And it is working because I removed Content-Type on my postman headers.
Make sure you are not using Content-Type on the headers.
I would recommend you to use express instead of body-parser, as body-parser got merged back in express a long ago.
I am using this code and it seems to work fine, setting the limit option to 200mb, of both express.json and express.urlencoded
app.use(express.json({ limit: "200mb" }));
app.use(express.urlencoded({ extended: true, limit: "200mb" }));
Source: express.json vs bodyparser.json

Categories

Resources