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
Related
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
I make a ajax call via code below and expect to see parameters passed nodejs app, but it always empty
#action postData() {
$.ajax({
url:"http://localhost:8080/sendMail",
ContentType:'application/json',
dataType:'json',
type:'post',
data:JSON.stringify({'message':'helloworld'}),
success:(result) =>{
..
})
If I make a post request within postman(adding raw string json parameters to body; {'message':'helloworld'}) its passed well and I see its logged. So whats wrong with this ajax call that i used in reactjsapp ?
Edited: it looks all parameters passed in browser fine but somehow nodejs unable to get them..
Since POST data is sent in the HTTP body, you need to parse the JSON in there to get it. Assumed you use express.js on the server side, you could use body-parser to do that:
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
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 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()
})
Express (or Connect's) bodyParser middleware is marked deprecated and users are advised to use instead:
app.use(connect.urlencoded())
app.use(connect.json())
However, when I run the an example from Node.js in Action, I use curl to fill out the form as suggested by the book:
curl -F entry[title]='Ho ho ho' -F entry[body]='santa loves you' http://abc:123#127.0.0.1:3000/api/entry
It doesn't work. req.body is not defined. Am I missing something? It works fine with bodyParser.
EDIT: SOLUTION as of Express 4
Parse json this way:
var bodyParser = require('body-parser');
...
app.use(bodyParser.json());
Parse urlencoded body this way:
app.use(bodyParser.urlencoded({extended: true}));
Then there is no deprecation warning. The extended: true (default) uses the qs module and false uses the querystring module to parse the body.
Don't use app.use(bodyParser()), that usage is now deprecated.
bodyParser is in fact the composition of three middlewares (see documentation and relevant source code): json, urlencoded and multipart:
json parses application/json request bodies
urlencoded parses x-ww-form-urlencoded request bodies
and multipart parses multipart/form-data request bodies, which is what you're interested in.
If you only specify json and urlencoded middlewares, the form data won't be parsed by any middleware, thus req.body won't be defined. You then need to add a middleware that is able to parse form data such as formidable, busboy or multiparty (as stated in connect's documentation).
Here is an example, using multiparty:
var multipart = require('connect-multiparty');
var multipartMiddleware = multipart();
app.use('/url/that/accepts/form-data', multipartMiddleware);
app.post('/url/that/accepts/form-data', function(req, resp) {
console.log(req.body, req.files);
});
Don't forget that by using such middlewares you allow anyone to upload files to your server: it then your responsibility to handle (and delete) those files.