GET vs HEAD methods in Express. EXAMPLE - javascript

How to implement HEAD method in Node.js with Express server-side for a given GET method?
Can someone provide an example of usage of HEAD mehod vs GET method?
I mean code like:
Index.js
app.get ("/root", function (req, res) {
//some code
})
app.head ("/root", function (req, res) {
//some code
})

Http Head request is only used to request HTTP headers from the server and server must not return a body in it.
app.head("/root",(req,res)=>{
res.set('x-user', 'abcd')
})
Http get request is only used to get some request some body and additional headers(if needed)
app.get("/root",(req,res)=>{
res.json({email:'test'})
})
Please note: Both the type of request should not change the state in the system. For changing the state use POST, PUT, PATCH or DELETE methods

Related

Request interceptors not modifying the value of request header in node js

I am using http-proxy-middleware to create a proxy and it's running successfully.
Before calling app.use('/',proxy_options);
I am trying to intercept my request and modifying the request header but updated value is not reflecting in headers.
app.use('/',(req,res,next)=>{
const token=getToken();
req.header['authorization']=token;
next();
});
Even I tried with req.header.authorization=token; and also without next();.
When I am trying to print the my request header authorization:'' is coming as blank.
Can any one let me know why this happening and how I can resolve this.
Any help or suggestions must be appreciated.
If your getToken() function is fetching token from other apis, then you should add await in front of it.
Try to use below code,
app.use('/', async (req,res,next)=>{
const token=await getToken();
req.headers['authorization']=token;
next();
});
You also need to replace header by headers, as mentioned above in code snippet.
It should work.

How to use get and post both in app.use middleware

I wish to know how can I have both get and post request handled by app.use the way I do it using app.route
app.use('/', (req, res, next) => {
if (isLaunched) {
return next()
}
// You can also render if you want
res.render('coming-soon')
});
How can I handle a post request to this?
According to https://expressjs.com/en/guide/using-middleware.html the syntax you already have is used for any type of HTTP request - including GET and POST. You can detect the method via req.method.
app.use() already handles ALL http methods, including GET and POST. You can see exactly which method it is for any given request by checking req.method.
If you had trouble with some GET or POST when doing this, then please show the specific code and the specific request that it didn't work for. If you didn't try it yet, then just try it as it should work just fine.
Middlewares are mounted using app.use(<middleware-name>) so, you can add it to all routes like you do for bodyParser/CORS etc.
If you want to mount for specific routes you can use
app.post("/example" , middleware, (req,res)=>{
res.send("Hello world")
})
Refer to Use middleware on specific routes

Nodejs + Express: How to get an element which made an HTTP GET request?

I am making a front using Express. I have a table where each row has a link that makes a GET request, so that the back-end (done with node.js) returns a file corresponding to that row.
All links make the url GET request like "/documents/table/file".
What I intend to do is for my express server to be able to know which link of what row makes the GET request with the req field of it in order to be able to return the corresponding requested file.
The request is being handled in my express server as follows:
router.get('/documents/table/file', async (req, res) =>{
//Get which element made the get petition
});
As I said before, I intend to know what link from which row of the table performs a request using the req field.
You need to pass the information about the row/item that makes the GET request, that is a must.
Now with Express there are a couple of ways to do this: Express routing.
1. Defining route params: req.params
GET Request: /documents/table/file/345 (345 is the row identifier name or id etc)
At nodejs express end:
router.get("/documents/table/file/:id", (req, res) => {
/*request parameter with this kind of route sits in req.params*/
console.log(req.params);
const requestedId = req.params.id;
});
2. Sending as query string parameters: req.query
GET Request: /documents/table/file?id=345
At nodejs express end:
router.get("/documents/table/file/", (req, res) => {
/*request parameter with this kind of route sits in req.query*/
console.log(req.query);
const requestedId = req.query.id;
});
The short version is: you can't know this.
The way this is normally handled that if a request is needed for a specific item (or row in a table), you need to add some relevant information to the url that can identify it yourself.
So if it's a GET request for /foo/get-file, and every 'file' has some kind of unique id, you might want to change your url to /foo/get-file/123 or /foo/get-file?id=123
Do you want to access specific file using get command? If so, here's an answer - Express router - :id?.
More precisely, you write something like router.get('/documents/table/file/:id), and this :id is available in req.params object.

Axios POST params show empty on server - using MERN stack

I want to update a document in Mongo, but when I send an Axios POST request to the server with params for the updates I receive nothing but a blank object on the server side - I'm using Node.js with an Express server (MERN stack).
I have tried the qs library module and Node's querystring module. I tried including headers with
'Content-Type': 'application/x-www-form-urlencoded' and 'application/json'.
My Axios POST request:
const A = 1;
const B = 2;
const data = { A, B };
console.log(qs.stringify(data)); // A=1&B=2
axios.post(url('upVote'), qs.stringify(data));
The server route:
app.post('/upVote', async (req, res) => {
console.log(req.params); // {}
await DB.updateVote(ID, collection, voteCount);
res.end();
});
The headers as shown by Chrome's DevTools.
... Also, all my axios.get() requests work fine and grab data from Mongo and send it back to my app properly, and the url/endpoints match.
There are a couple of ways to send data to the server with axios.
I see the confusion with the documentation in axios, I have not seen this usage before and it does seem to be broken upon looking at the request logs and object.
1) axios.post receives body of the request as a second parameter. So if you want to pass parameters to axios, you should do something like this:
const B = 2;
const data = { A: 1, B: 1 };
axios.post(url('upVote'), {}, { params: data });
Note that axios will handle stringification on it's own and that the third parameter is a config object.
On the server the params will be available at request.query
2) If you want to stringify the parameters yourself, then you should append them into your URL like so
axios.post(`url('upVote')?${qs.stringify(data)}`);
Same here, data on the server will be under request.query
3) It's generally better to use the body of the post request to transfer large data payloads for convenience. You should also consider what your caching strategies are and if they rely on request url without the consideration of request body it may be a concern.
axios.post(url('upVote'), data);
In this case data on the server will be under request.body
UPD: Originally forgot to mention that you will need a body-parser middleware to access request.body.
4) You can use axios without method shorthands which may be useful for some people
axios({
method: 'POST',
url: url('upVote'),
params: data
})
This is identical to the example in 1.
And all of them return a Promise which you can .then().catch() or await.
I think you want .body instead of .params.As you are sending data in body by post using axios. You are printing params which will print nothing for this url/api .
Try
console.log(req.body) // instead of req.params
If this did not work then please show us your react code.
Moreover
In react you have to add .then() after axios else it will say unhanded promise
To get params on server side you have to make some changes
In axios (react)
axios.post(url('upVote/param'), qs.stringify(data));
In server
app.post('/upVote/:params', async (req, res) => {
console.log(req.params)
.....
})
I think you are calling res.end(). I think it should be res.send(...)
This answer should help: https://stackoverflow.com/a/29555444/1971378

Redirecting get to post? res.redirect to POST

Here in the GET /facebook route i receive the authorization code from front-end after receiving that, i have to make a POST request to /facebook/signin
How can I redirect GET /facebook to POST /facebook/signin
router.get('/facebook', (req, res) => {
// res.send(req.query.code);
res.redirect('/facebook/sign'); // = GET /facebook/sign
});
POST route
router.post('/facebook/sign', (req, res, next) => {
console.log(req.query.code);
// i will do mine stuff....
});
You can also write 1 handler method and use it in both routes;
function doFacebookSignIn(req, res) {
// Your code here.
}
or
// Must be defined before using it in code.
var doFacebookSignIn = function(req, res) {
// Your code here.
};
router.get('/facebook', doFacebookSignIn);
router.post('/facebook/sign', doFacebookSignIn);
But as I pointed out in the comments, you should be aware that when using a request body in a GET request, there are some things to consider.
You cannot redirect GET to POST, a redirect is used to notify an HTTP client that a resource has changed location and should attempt the same request using the new location.
It is noted in the RFC that in some cases POST will be downgraded to GET when the request is re-issued.
Note: When automatically redirecting a POST request after
receiving a 301 status code, some existing HTTP/1.0 user agents
will erroneously change it into a GET request.
If a POST request is expected on the server, then the client should send a POST request rather than a GET request.

Categories