Sometimes GET returns 304 instead of 200 - node.js

I am using node.js and mongodb.
I seem to be receiving a 200 sometimes, and a 304 not modified other times.
router.get('/add-to-bag/:id', (req, res, next) => {
req.session.bag.push(req.params.id);
res.redirect('back');
});
});

I can't be sure what stack you're using to create the app. It looks like you're using Express.js to do routing. However, I can tell you why you're getting a 304.
From Wikipedia:
304 Not Modified (RFC 7232)
Indicates that the resource has not been modified since the version specified by the request headers If-Modified-Since or If-None-Match. In such case, there is no need to retransmit the resource since the client still has a previously-downloaded copy.[24]
A 304 means "hey, remember the last answer I sent you? It hasn't changed", and hence your browser would replay the last response it received from cache, without data transmission ever having taken place.
This means that your data is being added. But since it's the exact same data in the bag, instead of giving a 200 with the exact same data again, the server just issues a 304.
BTW: Your API isn't Restful. I'd recommend using POST to create new records instead of issuing a GET to a different URL. I recommend reading up on REST API design. It's pretty straightforward once you get the hang of it.

TL;DR: Use a POST request instead of a GET request.
GET requests should be used for getting things. A GET request should not affect the state of the application (i.e. of the server).
In your case, adding an item to the shopping bag is clearly a modification of the state of the server.
If you're not convinced, check out this answer
A GET is defined in this way in the HTTP protocol. It is supposed to be idempotent and safe.
If you use a POST request, not only will it fix you 304 issue, but it will also prevent some other possible bugs later on. (And it will be more correct.)

Did you try by disabling etag?
app.disable('etag');

Simply adding 'Cache-Control': 'no-cache', to my headers was able to bypass the 304 issue I was having. Seen in this answer here

Related

Is ending responses in Express with a status code always necessary or recommended?

I'm confused about this. I have seen a lot of people ending responses with just res.send();. At the same time, some tend to include a status code, like res.status(422).send();. I understand that this is useful when a user, for example, has sent a request to /log-in/ with data that represents a type different from the one needed and appropriate. In such cases, I'm ending my responses with res.status(422).send();. If I'm expecting a username, but I instead receive an array, it seems to me that such an approach is appropriate. However, if everything is technically alright and the user has just entered a username that does not exist, do I need to include a status code? When such a thing happens, a message under the form will be displayed instead. And res.send("This username does not exist."); is the function I would call. Should I call res.status(401).send("This username does not exist."); instead?
Technically you are not forced to use status codes however it's recommended to follow the best practices.
When the user does not exist return 404 not 401. 401 is unauthorized
When user input is not expected, that's validation error(bad request) and return 400 instead of 422. 422 is used in slightly different scenarios.
Read more about it 400 vs 422
More details about http status codes
Yes, status codes are very important as a good practice I would prefer 404 instead of 401 in your case res.status(404).send("This username does not exist.");
stackOverflowAnswer
Why do we use the status code?
To make your debug life easy/ better error handling and to log the error in production to know the severity of the error your application has in case it crashes.
How to Specify statusCode in Node.js
When to use what status code
By default, Express answer all endpoints with 200 unless you didn't specified an endpoint, in this case it will automatically reply with 404.
by the way, Express also has res.sendStatus() function that ends the request and sending status
This has to do with your api design. Generally you would be publishing your api specs (Api specification) and there would mention how your client can find out if something is going wrong or going fine.
HTTP Response code are some of easiest way to inform client about outcome of request. So they don't have to go inside the payload of response to check what was outcome. Since most of codes are well know and there is consensus you will write more standard code which works with network elements like proxies, load-balancer etc and understandable developers.
Advantages of status codes

How to know the size of an HTTP request before it reaches its destination?

I am studying NodeJS and I have learned about streams and buffer. I found it very interesting because it occurred to me to use it on an HTTP server, since if a request is too big, the data can be sent little by little, especially when using the verb POST to upload big files for example. The problem is that not all data (files at this case) is very big. Is there a way to know the size of a request before it reaches its destination?
From the receiving end, you can look at the Content-Length header.
It may or may not be present, depending upon the sender. For info about that, see Is the Content-Length header required for a HTTP/1.0 response?.

Node post request body gets truncated

when trying to post a WakeUp event with a JSON body to the Alexa events API using nodejs with axios or request-promise, the API always returns an error 500.
I posted to an online endpoint to actually see what gets posted and learned that the post body gets truncated which obviously results in invalid json. I abstracted the problem and tried to run it from a virgin nodejs installation by using repl.it and the result is the same.
Interestingly enough, there seems to be a relation between the length of the header and the body. So when I shorten the auth token in the header, more characters of the body get transferred. If I shorten the long tokens in the body to about 450 to 500 characters (it seems to vary) the whole request gets through. Obviously this is not a solution, because the tokens are needed for authentication.
When I experimented with the axios version used lowering it to 0.10 I once got a result but posting again lead to another 500. If I post often enough some requests get trough complete, even on the current axios version. I also tried using request-promise with the same outcome.
I got the feeling that I made a really stupid mistake but I can't find it and I really couldn't find anything on this topic, so it's driving me crazy. Any help would be greatly appreciated!
This looks like a tricky one.. first of all, I don't think you're making a really stupid mistake. It looks to me like one of the low-level modules doesn't like something in the POST body for some reason (really weird.).. I've played about with this and I'm getting exactly the same behaviour with both Axios and Request.. if I comment out the tokens (correlationToken and bearer token ) everything works fine.
If I test this locally, everything works as it should (e.g. set up express server and log POST body).
Also posting to https://postman-echo.com/post works as expected (with the original post data)..
I've created this here: https://repl.it/repls/YoungPuzzlingMonad
It looks to me like the original request to http://posthere.io is failing because of the request size only. If you try a very basic POST with a large JSON body you get the same result.
I get the same result with superagent too.. this leads me to believe this is something server side...
This was not related to the post request at all. The reason for the error after sending the WakeUp event was the missing configuration parameter containing the MACAdresses in the Alexa.WakeOnLANController interface.
I used the AlexaResponse class to add the capability via createPayloadEndpointCapability which had not been modified to support the "new" WakeOnLANController interface yet.
It's a pity that the discovery was accepted and my WOL-capable device was added to my smart home devices although a required parameter was missing :(
posthere.io cutting off long post bodys cost me quite a few hours... On the upside, I go to know many different ways of issuing a post request in node ;)
Thanks again Terry for investigating!

Receiving "400 Bad Request" for /oauth/access_token

I have approved for public_content clientId. To get access token, I send a request to www.instagram.com:
GET /oauth/authorize?client_id=MyClientId&redirect_uri=MyRedirectURL&response_type=code&scope=likes+comments+public_content HTTP/1.1`
After authentication, the browser redirects me to MyRedirectURL and I can get the code from the URL.
With this code I send a request to api.instagram.com:
/oauth/access_token HTTP/1.1
client_id=MyClientId&client_secret=MyClientSecret&grant_type=authorization_code&redirect_uri=MyRedirectURL&code=CodeFromURL`
But sometimes I get response HTTP/1.1 400 Bad Request.
This situation continues for a few hours, and sometimes for a day. It is interesting that the problem is very unstable. I may have two client apps that make identical requests, and one app will work fine, while the other will fail at the same time. Looks like it is a problem somewhere in the Instagram infrastructure.
Instagram is no longer supporting custom schemas for your callback urls. That was my problem, I changed it to https and the problem was solved.
I think you should prefer this document of Instagram.
You may also receive responses with an HTTP response code of 400 (Bad
Request) if we detect spammy behavior by a person using your app.
These errors are unrelated to rate limiting.
It seems like , we can not use http://localhost/... in call back url. Instagram may have restricted it.
It worked for me, when I have added live Ip of my aws server. for example http://xx.xx.xx.xx/.. instead of localhost.

Accessing response headers from NodeJS/ExpressJS before a response is sent

Is there a way to see which response headers will be present on an HTTP response (and possibly set new HTTP headers)? It seems like once res.send() or res.json() is called, ExpressJS takes over, and there is no way to "intercept" the response before it is sent to the client. Note that I've seen this asked and answered for different platforms, its just not clear whether this is possible in NodeJS/ExpressJS.
I ended up asking this on the ExpressJS issues board. The answer from dougwilson:
For both use-cases you listed, you want to alter/inspect the response
headers. https://www.npmjs.org/package/on-headers is what you would
use.
Source: https://github.com/strongloop/express/issues/2327

Resources