I have an API that works as expected from all incoming requests using application/json request. But recently I encounter the need to process a POST request from x-www-form-urlencoded and the body of the request is always empty.
I test the API using POSTMAN and works great when I send the request using the option raw with JSON(application/json). But when send data using x-www-form-urlencoded the body is empty.
The route for the POST is app/api/sensor, and the files are the following:
app.js
var express = require('express');
var app = express();
.......
app.use(express.json());
app.use(express.urlencoded()); // THIS SHOULD WORK!
......
sensor.js POST
......
sensorRoute.post('/', (req, res, next) => {
console.log(req.body);
const temperature = req.body.temperature;
console.log(temperature);
if (!temperature) {
return res.status(400).send({'res': 'Missing data'});
} else {
return res.status(200).send({'res': 'OK'});
}
});
....
The expected result should show the data that is been send using postman in the req.body and not an empty object, and work the same as the application/jason.
change
app.use(express.urlencoded());
to
app.use(bodyParser.urlencoded({
extended: true
}));
The extended option allows to choose between parsing the URL-encoded data with the querystring library (when false) or the qs library (when true). The "extended" syntax allows for rich objects and arrays to be encoded into the URL-encoded format, allowing for a JSON-like experience with URL-encoded. For more information, please see the qs library.
Defaults to true, but using the default has been deprecated. so add the option extended: true
Related
this is my index.js code and it returns an empty object even though data is passed on from the front-end
const express = require("express");
const cors = require("cors");
const app = express();
app.use(cors());
app.use(express.json());
app.post("/api/register", (req, res) => {
console.log(req.body);
res.json({ status: "ok" });
});
app.listen(8000, () => {
console.log("listening on port 8000 . . . ");
});
For the specific case you're talking about, you usually need oa body parser to be able to access the form input fields. The minimum example that I advice you to build above it is the following:
// parse requests of content-type - application/json
app.use(express.json());
// parse requests of content-type - application/x-www-form-urlencoded
app.use(express.urlencoded({ extended: true }));
Some other hints
Make sure that the request is being submitted with the header Content-Type: application/x-www-form-urlencoded or Content-Type: application/json
Check if there any CORS problems
Here's More reference for you
The main reason this does not work is
some how the data passed in body is in text format while req.body is
expecting json data
make sure to double chek the 'Content-Type':'application/json' is set on the request headers
if you are using multipart/form-data or require a file upload from frontend you will need a multer as middleware for your post/patch requests, otherwise you can set your frontend to send application/json
[edit]
this line looks missing from your index.js
app.use(express.urlencoded({extended: true}))
I'm trying to take a json collection of data and send it with postman or Advanced REST Client. The biggest thing I'm getting stuck with with is where the data is. I can't seem to find it in any part of the request. Note this must be done using express.
app.put('/api/', function (req, res) {
//Get data and replace table in database
res.send("RECEIVED");
});
You can use body-parser to parse the request and provide you all that submited data through request.body.data if you send you data as a form-data or request.params.data if you send your data as a query parameter.
npm install body-parser --save
And import it and use it as a middleware
var bodyParser = require("body-parser");
// some other code goes here like
// var express = require("express"):
// var app = express()
// and here attach the body-parser middleware like thiss
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
when you make a request with any Advanced REST client each key in the JSON that you pass to the request body will be accessible as request.body.key you can learn more about body-parser body-parser doc
I'm using express 4 with body-parser like so
var bodyParser = require('body-parser');
...
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
When I added dicer it's like body parser stops working. I no longer have any post params in req.params or req.body or req.query.
Is there a way to use body parser manually? Does body parser check for multipart forms data and just do nothing ... assume another lib will handle it?
Also, I feel I should note, that I am using dicer to parse the multipart form data for a reason and I don't want to use busboy or multer or xyz if possible.
To answer your question "Is there a way to use body-parser manually?"
the answer is yes and it is the recommended way of using it. Referring to the body-parser documentation:
express route-specific
This example demonstrates adding body parsers specifically to the routes that need them. In general, this is the most recommend way to use body-parser with express.
(I added some semi-colons because they would keep me up at night)
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
// create application/json parser
var jsonParser = bodyParser.json();
// create application/x-www-form-urlencoded parser
var urlencodedParser = bodyParser.urlencoded({ extended: false });
// POST /login gets urlencoded bodies
app.post('/login', urlencodedParser, function (req, res) {
if (!req.body) return res.sendStatus(400);
res.send('welcome, ' + req.body.username);
})
// POST /api/users gets JSON bodies
app.post('/api/users', jsonParser, function (req, res) {
if (!req.body) return res.sendStatus(400);
// create user in req.body
})
So depending on which routes you need body-parser for, you can implement it with some custom middleware. Now, I have not tested this, but I'm assuming you could also implement it in the same way as other express middleware:
// URL encoded bodies
app.use('/api/url/encoded/endpoint', bodyParser.urlencoded({ extended: false }));
// JSON encoded bodies
app.use('/api/json/encoded/endpoint', bodyParser.json());
Where any routes that match the above endpoints, such as
app.use('/api/url/encoded/endpoint/test', function (req, res) { ... });
would be parsed using the appropriate middleware as long as they are below the middleware declarations in your code.
To try to answer your whole question, I would say that it would be safe to try not using either parser globally. Keep your parsers api endpoint specific and you shouldn't run into any problems.
Edit:
So your question is a little unclear. You would like to use body parser for multipart/form-data? "Body-parser does not handle multipart bodies, due to their complex and typically large nature." Again, I haven't tried it but maybe you could give the bodyParser.raw({ type: ... }) function a try if that's the case. If not, then you need to use dicer in a custom middleware function in which you check for the correct content type.
I am going through the book Web Development with Node and Express and have hit a snag.
I was instructed to put the below in my application file, but it looks like body-parser is deprecated and will not work. How can I achieve the same functionality?
This is my current code:
app.use(require('body-parser')());
app.get('/newsletter', function(req, res){
// we will learn about CSRF later...for now, we just
// provide a dummy value
res.render('newsletter', { csrf: 'CSRF token goes here' });
});
app.post('/process', function(req, res){
console.log('Form (from querystring): ' + req.query.form);
console.log('CSRF token (from hidden form field): ' + req.body._csrf);
console.log('Name (from visible form field): ' + req.body.name);
console.log('Email (from visible form field): ' + req.body.email); res.redirect(303, '/thank-you');
});
Just wanted to update this thread because I tried the solution above and received undefined. Express 4.16+ has implemented their own version of body-parser so you do not need to add the dependency to your project. You can run it natively in express as follows:
app.use(express.json()); // Used to parse JSON bodies
app.use(express.urlencoded()); // Parse URL-encoded bodies using query-string library
// or
app.use(express.urlencoded({ extended: true })); // Parse URL-encoded bodies using qs library
Source: Express JS — body-parser and why may not need it
See also: query-string vs qs
From: bodyParser is deprecated express 4
It means that using the bodyParser() constructor has been deprecated, as of 2014-06-19.
app.use(bodyParser()); //Now deprecated
You now need to call the methods separately
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded());
app.use(bodyParser.json());
And so on.
Do not use body-parser anymore
Since Express 4.16+ the body parsing functionality has become builtin with express
So, you can simply do
app.use(express.urlencoded({extended: true}));
app.use(express.json()) // To parse the incoming requests with JSON payloads
from directly express, without having to install body-parser.
you can now uninstall body-parser using npm uninstall body-parser
And to get the POST data content, you can use req.body
app.post("/yourpath", (req, res)=>{
var postData = req.body;
//Or if body comes as string,
var postData = JSON.parse(req.body);
});
I want to log all the query parameters which are passed to my endpoint. whenever they call me ie through GET , POST. i am able to print all the GET query params but struggling with POST params.
i used req.body but that doesnt work it just prints [Object object] even JSON.stringify didnt help.
Can any one point me to right source to look for it
So POST parameters arrive in the HTTP request body, and this is handled as a stream of data chunks by node.js. So the first thing you must do is make sure you assemble the stream of chunks into a complete piece of data. Then you may want to parse it as either url encoded or JSON if that's what it is. The standard middleware for this is body-parser. You set it up like they say in the README:
const express = require('express')
const bodyParser = require('body-parser')
const app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
// parse application/vnd.api+json as json
app.use(bodyParser.json({ type: 'application/vnd.api+json' }))
app.use(function (req, res, next) {
console.log(req.body) // populated!
next()
})