I am using express.js (v 4.13.4), node.js (v 0.12.5) and body-parser (v 1.13.2) to create a simple chat RESTful API.
I have this url path which must be called by the user:
http://myhost/chat/room/:roomId/message/:messageId
Body-parser is set like this:
var app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
I am unable to read the first url parameter :roomId but the :messageId is available.
I am accessing those parameters using req.params.roomId and req.params.messageId in request callback function.
Question:
Is it wrong to have parameters in the middle of a url?
Why would the application not parse :roomId?
The parameters roomId and so are send as query parameter therefore req.params.roomId is required to fetch.
Another way to do is send params as body, that way URL will be clean and then to access params body-parser is required.
To send params in body, create a post request through postman and specify params there.refer this for sending params in body
It is working in my case.
var app = require('express')();
var bodyParser= require('body-parser');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.get('/chat/room/:roomId/message/:messageId', function(req, res){
console.log('Room Id: '+req.params.roomId);
console.log('Message Id: '+req.params.messageId);
res.sendStatus(200);
});
app.listen(3000);
Now, if I try to access localhost:3000/chat/room/1/message/100, I get
Room Id: 1
Message Id: 100
Please check the spelling of roomId. May be typo can be the issue.
Thank you for your answers Mukesh Sharma and Himani Agrawal.
I found the issue now, here it is:
If I register a room router like this:
var RoomRouter = express.Router();
RoomRouter.get('/:roomId/message/:messageId', function(req, res) {
console.log('Room Id: '+req.params.roomId);
console.log('Message Id: '+req.params.messageId);
res.status(200);
res.send("Ok");
});
app.use('/chat/room', RoomRouter);
:roomId and :messageId are received accordingly.
But if I register the room router like this (as it was when I posted the error) :roomId is not available.
var RoomRouter = express.Router();
RoomRouter.get('/message/:messageId', function(req, res) {
console.log('Room Id: '+req.params.roomId);
console.log('Message Id: '+req.params.messageId);
res.status(200);
res.send("Ok");
});
app.use('/chat/room/:roomId', RoomRouter);
This was my issue, I don't know exactly why the url would be parsed differently in two different situation but I am sure this has a logic somewhere.
Related
I'm creating a web platform with a Nodejs server. I'm trying to retrieve urlencoded data sent from my front but can't manage to.
How I send the GET request :
xhr.open("GET", address + "?limit=1&offset=1",true);
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(null);
xhr.addEventListener("readystatechange", processRequest, false);
On the server side :
const bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: true });
app.get('/guid_list', urlencodedParser, function (req, res) {
console.log(req.body.limit);
console.log(req.body.offset);
var headerjwt = HeaderGetJWT(req);
...
}
I have no problem retrieving the jwt token I'm sending, but always get undefined for urlencoded parameters.
I was wondering if I should use multipart content type instead, since I'm sending both a token and urlencoded data ? And maybe "multer" module in that case, since body-Parser does not support that content type.
I would suggest accessing your parameters in Node.js as follows (since they are being passed as query parameters):
app.get('/guid_list', parser, function (req, res) {
console.log("req.query.limit:", req.query.limit);
console.log("req.query.offset:", req.query.offset);
});
or just log all parameters:
app.get('/guid_list', parser, function (req, res) {
console.log("req.query:", req.query);
});
I am submitting a form and the following gets called...
handleLogin(){
fetch('http://localhost:8080', {
method: 'post',
body: JSON.stringify({
username: this.state.username,
password: this.state.password
})
});
}
It makes a POST request to my restAPI. The request works, but the data is not passed...
app.post('/', function(req, res, next) {
console.log(req.body.username);
....
This prints out undefined, meaning password and username are not passed through the call. What am I doing wrong?
Express by default doesn't parse the body of the request. In order to enable parsing, you will need to use a middleware such as body-parser. You can find some information in the express docs.
Also, the client side needs to indicate that it's sending json data. That can be achieved with the Content-Type header. There is a pretty good tutorial about fetch() here. You can jump directly to the Request Headers section which is relevant for your question.
var express = require("express");
var app = express();
var bodyParser = require('body-parser');
const PORT = process.env.PORT || 7070;
const BASEURL = process.env.BASEURL || 'http://localhost/7070';
app.use(bodyParser.urlencoded({extended:true}));
app.listen(PORT, function() { console.log('Server running on'+BASEURL);
});
I'm having some troubles trying to stablish a REST API with nodeJS and express. The following code defines two routes, "stores" and "user".
Surprisingly, the route to "/user" is working nice but when a request arrives to "/stores" the request body appears undefined. I've searched for a solution but nothing seems to work for me.
Both controllers have the same structure.
What am I doing wrong?
var express = require("express"),
app = express(),
bodyParser = require("body-parser"),
methodOverride = require("method-override"),
mongoose = require('mongoose');
// Connection to DB
mongoose.connect('mongodb://localhost/appDB', function(err, res) {
if(err) throw err;
console.log('Connected to Database');
});
// Middlewares
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(methodOverride());
//Import models and controllers
var userModel=require("./models/user.js")(app,mongoose);
var storeModel=require("./models/store.js")(app,mongoose);
var usersController=require("./controllers/users.js");
var storesController=require("./controllers/stores.js");
//Router options
var router=express.Router();
router.route('/stores')
.get(storesController.getNearestStores);
router.route('/user')
.post(usersController.addUser);
app.use(router);
//Start server
app.listen(3000, function() {
console.log("Node server running on http://localhost:3000");
});
Thank you very much.
P.S.:First time with nodejs and express(and even mongo)
This is because there is no body on a GET request in the http standard. Only POST and PUT.
What you want to do instead is use a query string
get
/stores?location=mystore
this way on your callback you have access to req.query
req.query
{
location: 'mystore'
}
HTTP GET with request body
This gave me the solution, get requests don't accept parameters under HTTP standard.
I'am trying to handle http post message from Mailgun bounce webhook. When sending it to Mailgun's Postbin service all data is found of course. But I'm now sending that POST to my localhost server for development purposes and all I get is empty json array. I use Test Webhook.
Intent is to keep this simple as possible besides our main service. That for I started using nodejs/expressjs to create stand alone webservice to work as relay to receive POST messages of email bounces from Mailgun and inform admins about bounced email addresses.
Now I can't figure why I don't get the same data as is visible in Postbin.
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var mailgun = require('mailgun-js')({apiKey: 'key-...', domain: 'mymailgundomain.com'});
app.use(bodyParser.urlencoded({
extended: true
}));
function router(app) {
app.post('/webhooks/*', function (req, res, next) {
var body = req.body;
if (!mailgun.validateWebhook(body.timestamp, body.token, body.signature)) {
console.error('Request came, but not from Mailgun');
res.send({ error: { message: 'Invalid signature. Are you even Mailgun?' } });
return;
}
next();
});
app.post('/webhooks/mailgun/', function (req, res) {
// actually handle request here
console.log("got post message");
res.send("ok 200");
});
}
app.listen(5000, function(){
router(app);
console.log("listening post in port 5000");
});
I'm running this from Mailgun's Test Webhook using url like http://mylocalhostwithpublicip.com:5000/webhooks/mailgun
Code structure is copied from https://github.com/1lobby/mailgun-js. Probably I'm missing something fundamental here as I can't figure it out myself.
The reason you're not seeing req.body populated is because the body-parser module does not support multipart/form-data requests. For those kinds of requests you need a different module such as multer, busboy/connect-busboy, multiparty, or formidable.
If your content-type (shown by logging console.dir(req.headers['content-type'])) is 'application/x-www-form-urlencoded', and you're using body-parser, try adding the following line:
bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({ extended: false }))
to make it work with multer, you can use .any() (version 1.1.0)
for me it worked like this: (assuming multer is included and declared as "multer")
post('/track', multer.any(),function(req, res){
//if body is a string, parse the json
var data=(typeof req.body=='string')?JSON.parse(req.body):req.body;
//if data is an object but you can't verify if a field exists with hasOwnProperty, force conversion with JSON
if(typeof data=='object' && typeof data.hasOwnProperty=='undefined')
data=JSON.parse(JSON.stringify(data));
//data is your object
});
var multer = require('multer');
var msg = multer();
post('/track', msg.any(), function(req, res){
console.log(req.body);
}
I make a custom parser for get data in req.body when the Content-type = 'multipart/alternative'
https://github.com/josemadev/Multiparser/
I am using an AngularJS Resource to make an ajax post to a node js server running express. However I am unable to access the post payload parameters on the NodeJS side.
I have a service set up:
angular.module('app.services', ['ngResource'])
.factory('PostService', function($resource) {
return $resource('/postTest');
});
and in the controller I have:
function UserCtrl($scope, PostService) {
//query for the users
$scope.testPost = function() {
var stuff = {firstname: 'some', lastname:'person'};
PostService.save(stuff,function(data) {
console.log('called save on PostService');
});
};
}
I can see the payload inside of the http header:
{"firstname":"some","lastname":"person"}
however, when I get to the NodeJS route to process it, I am not sure how to access the parameters:
(output from node console): inside test stuff
req.params undefined
app.post('/postTest', function(req, res) {
console.log('inside test stuff');
console.log('req.params ' + req.param('stuff'));
})
I have created a fiddle at: http://jsfiddle.net/binarygiant/QNqRj/
Can anyone explain how to access the parameters passed by the post in my NodeJS route?
Thanks in advance
If "{"firstname":"some","lastname":"person"}" is in the body of the post in json?
You'd access it differently.
Using express.bodyParser(), req.body.firstname will get you the firstname
app.use(express.bodyParser());
Then
app.post('/postTest', function(req, res) {
console.log('inside test stuff');
console.log(req.body.firstname);
})
You need to set body parser in your App
for example in ExpressJs 4,
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));