What does the first string parameter of app.post do? - node.js

I saw an example of app.post() function. What does the '/' mean? Are we required to use post and get methods in conjunction or can we just use one method?
app.post('/', function(req, res){
return;
});

The '/' is the root directory of your website. So that function would handle post requests for foobar.com/ . You don't have to use post and get methods in conjunction. Normally I use get and only use post for routes that I want to receive post data.

The code you posted means you're setting up the server to "listen" to the root url and execute the callback when the browser hits that url.
So, assuming you're using port 80, your url would be: http://localhost:80/
Since you're using the post method, then the callback will be executed when a post request is received on that url.
If you were to instead, use the get method, then you could just navigate to that url writing it on your browser address bar.
That way you can set all the endpoints for your web app.
Edit
If you want to know when to use post, get, and the other methods, you might want to check out this answer: Understanding REST: Verbs, error codes, and authentication

when you call app.post or app.get, you are listening for post or get requests, respectively. The first argument to these calls is the route at which you are listening for the request. so in the code below:
app.post('/', function (req,res) {
res.send("hello");
}
you are telling the server to call that function when someone makes a post request to the root of your domain (mydomain.com/).
likewise, the code below would tell the server to listen for get requests at "/getroute" (mydomain.com/getroute).
app.get('/getroute', function (req, res) {
res.send('hello');
}
post requests and get requests can be used seperately and do not have to be used in conjunction on the same route.

Look, the first parameter of app.post() is the route at which post data is received, which is sent by HTML form(action = '/') mean action attribute of your form tag, it is the route at which your HTML form will send your data. So, it no connection with the app.get parameter.

Related

node.js/express: use router.route() with middleware functions

I would like to use the method route() on an express router to service a specific route with different HTTP methods. The following code works fine:
var express = require('express');
var router = express.Router();
router.route('/register')
.get(adm.signUpForm)
.post(adm.signUp);
However, when trying to use a middleware on the post route, I'm getting stuck. The following code works:
// LOGIN processing
router.post('/login', passport.authenticate("local", {
successRedirect: '/',
failureRedirect: '/login'
}), function(){
//empty
});
Here, the middleware function passport.authenticate(...) is called to check if the user credentials are valid or not. Authenticated users get re-directed to the homepage at "/"; Unknown users (or with incorrect password) get re-directed back to the "/login" form.
Now, I would like to re-factor this code and use something similar to the code example shown above (sign-up route), i. e. I would like to use router.route('/login).xxxx to service HTTP request xxxx on route '/login'. How can I tell express to use my passport.authenticate middleware function on the POST request to '/login'?
router.route('/login')
.get(adm.loginForm)
.post(<my-middleware-function ???>, adm.login);
... where adm.loginForm is the end-point function that issues the login form upon a GET request to /login and adm.login is the end-point function that should be called when the server receives a POST request on this route, i. e. once the login form is submitted.
To the best of my knowledge, the express (4.x) documentation doesn't mention anything about installing a middleware function for a specific route and (at the same time) a specific HTTP request. I know that router.route('/login').use() can be used to install a middleware function for all HTTP requests on this route, but I only want my middleware to be called upon POST requests.
Any suggestions? Thanks.
You can add them where you mentioned:
router.route('/login').post(checkPassport, adm.login)
You can also chain them together:
router.route('/login').post(checkPassport).post(adm.login)
checkPassport is the middleware you'll need to write that handles the passport authentication logic

node express handling POST and GET as a single request

I would like to handle both POST and GET requests as a single request, such that all of my routings and subsequent functions only need to process a single request, rather than duplicating everything once for GET and again for POST.
So I figure the simplest way of doing this is to convert a POST to a GET early on using middleware, is there any problem with this ?
if(req.method=='POST'){
req.method = 'GET';
req.query = req.body;
delete(req.body);
}
You can have the same handler function for the both requests i.e
app.get('/', handlerFunction);
app.post('/', handlerFunction);
You can have express respond to all POST requests as 302 redirects to the same URL (these are always GET requests).
Here's some sample code:
// Redirect all post requests
app.post('^*$', function(req, res) {
// Now just issue the same request again, this time as a GET
res.redirect(302, req.url);
});
});
Side note: this will work but I wouldn't recommend this as a long term solution. If you decide you do need to handle POST requests differently from GET requests and the maintainability will become a pain. In the long run, you're better off having a clear definition for how to handle POST and GET requests rather than treating them the same.
Recommended approach is to have the same handler function for both in this case. for eg.
app.get('/path', handler);
app.post('/path', handler);

Node and Express, getting all (custom) methods with .all()

In Node and Express, I'm trying to get all traffic sent to a URL like this.
APP.all('/testCase', function(req, res) {
console.log('Im called with the method: ' + req.method);
});
If I now do:
curl -X GET http://localhost:3000/testCase it works fine, I get the response: Im called with the method: GET
But when I do:
curl -X INSERT http://localhost:3000/testCase I'm getting: curl: (52) Empty reply from server
What Am I doing wrong? I will have many custom methods
The INSERT method is not supported by the node http parser. To see a list of the HTTP methods supported, you can run node -pe "require('http').METHODS". In order to support custom HTTP methods, one would have to patch core itself (specifically the http parser).
app.all(path, callback [, callback ...])
This method is like the standard app.METHOD() methods, except it
matches all HTTP verbs.
It’s useful for mapping “global” logic for specific path prefixes or
arbitrary matches. For example, if you put the following at the top of
all other route definitions, it requires that all routes from that
point on require authentication, and automatically load a user. Keep
in mind that these callbacks do not have to act as end-points:
loadUser can perform a task, then call next() to continue matching
subsequent routes.
The most commons HTTP methods is:
GET
HEAD
POST
PUT
DELETE
TRACE
CONNECT

How to push a sequence of html pages after one request using NodeJS and ExpressJS

I am turning around in stackoverflow without finding an answer to my question. I have used expressJS fur several days in order to make an access webpage that returns first an interstitial and then a webpage depending on several informations I can get from the requester IP and so on.
My first idea for the interstitial was to use this piece of code:
var interstitial = function(req, res, next) {
res.render('interstitial');
next();
}
router.get('/', interstitial, nextPage);
setting a timeout on the next nextPage callback function of router.get().
However it looks that I could not do that. I had an error "Error: Can't set headers after they are sent.". I suppose this is due to the fact that res.render already give a response to the request and in the philosophy of express, the next function is passing the req, res args for another reply to another function that possibly could do it. Am I right?
In that case, is there a way to give several answer, with timeout to one request? (a res.render, and after that in the next callback a rest.send...).
Or is this mandatory to force client to ask a request to give back another response? (using js on the client side for instance, or timers on client side, or maybe discussing with client script using socket.io).
Thanks
Not sure I fully understand, but you should be placing all your deterministic logic within the function of the handler you're using for your endpoint.
Kinda like so:
router.get('/', function(req, res){
var origin = request.origin;
if (origin == '11.22.33.44'){
res.send('Interstitial Page.');
}else{
res.send('Home Page');
}
});
You would replace the simple text responses with your actual pages, but the general idea is that once that endpoint is handled you can't next() it to secondary handler.

Express wont match url to route when coming from remote server

I'm setting up a site that posts to a remote server. The user performs some steps on this remote server and when the user is done. The server issues a get request with a bunch of query parameters to my server.
The thing is that this request never arrives at the controller method it is supposed to.
I have a custom middleware that intercepts all requests and i am doing some logging in there, i can see there every time this request arrives to my server but express doesn't seem to match it to the controller.
However if i go into my browser and do the request from there with the exact same path and query string it works fine.
I thought maybe the remote server was using a proxy so i enabled trust proxy in express but that didn't make any difference.
I have tried changing the route path and that didn't make a difference.
I don't know what code would be helpful since it is pretty standard express code. I have tried putting the route before all the middleware and the request still bypassed the controller and was logged by my logging middleware.
I'm completely baffled, anyone got any idea what could be causing this?
EDIT:
Here is some of the code I'm using. This is not the exact setup I'm trying but I have tried to make it work this way to rule out my routing logic and this example has the exact same problem. I tried putting the app.get above the middleware and the request from the external server still bypassed the app.get and went directly to the middleware.
app.use(function(req, res, next) {
console.log('path', req.method, req.path, req.query);
});
app.get('/payments/success', function (req, res) {
console.log('SUCCESS', req.query);
res.status(200).send();
});
Here is the result of the middleware logging a request arriving from the remote server(i removed the variables logged from the request query because it is sensitive information, they are returned just the way they are supposed to):
path GET /payment/success {
variable: 'variable",
}
If anyone needs any more information from the request object i will provide it.

Resources