Why are multiple requests being processed for a single browser request? - node.js

Note: I am very new to node, and I have a VERY simple node site running based upon this example (http://blog.falafel.com/Blogs/BasemEmara/basem-emara/2014/03/18/getting-started-with-node.js-for-windows)
My code is:
var http = require('http');
var reqCount = 0;
http.createServer(function (req, res) {
reqCount++;
res.writeHead(200, { 'Content-Type': 'text/plain' });
console.log(reqCount);
res.end('Request: ' + reqCount);
}).listen(3000);
In the browser I initially get 1, hit refresh and get 3, 5, 7
And in the console I am getting every int, two per request
Why is this executing twice for each request?
I also know that I will not be handling requests directly, but wanted to start basic and then include express.

This may be /favicon.ico request done by your browser.
You can also print request url from req object to see that:
console.log(req.url);

Related

Node.js GET API is getting called twice intermittently

I have a node.js GET API endpoint that calls some backend services to get data.
app.get('/request_backend_data', function(req, res) {
---------------------
}
When there is a delay getting a response back from the backend services, this endpoint(request_backend_data) is getting triggered exactly after 2 minutes. I have checked my application code, but there is no retry logic written anywhere when there is a delay.
Does node.js API endpoint gets called twice in any case(like delay or timeout)?
There might be a few reasons:
some chrome extensions might cause bugs. Those chrome extensions have been causing a lot of issues recently. run your app on a different browser. If there is no issue, that means it is chrome-specific problem.
express might be making requests for favicon.ico. In order to prevent this, use this module : https://www.npmjs.com/package/serve-favicon
add CORS policy. Your server might sending preflight requests Use this npm package: https://www.npmjs.com/package/cors
No there is no default timeouts in nodejs or something like that.
Look for issue at your frontend part:
can be javascript fetch api with 'retry' option set
can be messed up RxJS operators chain which emits events implicitly and triggers another one REST request
can be entire page reload on timeout which leads to retrieve all neccessary data from backend
can be request interceptors (in axios, angular etc) which modify something and re-send
... many potential reasons, but not in backend (nodejs) for sure
Just make simple example and invoke your nodejs 'request_backend_data' endpoint with axois or xmlhttprequest - you will see that problem is not at backend part.
Try checking the api call with the code below, which includes follwing redirects. Add headers as needed (ie, 'Authorization': 'bearer dhqsdkhqd...etc'
var https = require('follow-redirects').https;
var fs = require('fs');
var options = {
'method': 'GET',
'hostname': 'foo.com',
'path': '/request_backend_data',
'headers': {
},
'maxRedirects': 20
};
var req = https.request(options, function (res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function (chunk) {
var body = Buffer.concat(chunks);
console.log(body.toString());
});
res.on("error", function (error) {
console.error(error);
});
});
req.end();
Paste into a file called test.js then run with node test.js.

How to tell if request was from browser or browser extension

When I run the following code I get two requests from my Chrome browser and have narrowed it down to one extension just by disabling it in chrome, but my question is how do I tell from my server side code which is the browser request and which is the extensions request
var http = require('http');
var server = http.createServer((request, response) => {
if (request.url == '/favicon.ico'){
console.log('ignore icon request')
}else{
console.log(request.url);
response.write('hi');
response.end();
}
});
server.listen(3000);
calling http://localhost:3000/, my output ends up being
/
/
ignore icon request
so similar to what I did with ignoring the favicon, is there a simple way of ignoring that extension request?

Node.js - Stream Binary Data Straight from Request to Remote server

I've been trying to stream binary data (PDF, images, other resources) directly from a request to a remote server but have had no luck so far. To be clear, I don't want to write the document to any filesystem. The client (browser) will make a request to my node process which will subsequently make a GET request to a remote server and directly stream that data back to the client.
var request = require('request');
app.get('/message/:id', function(req, res) {
// db call for specific id, etc.
var options = {
url: 'https://example.com/document.pdf',
encoding: null
};
// First try - unsuccessful
request(options).pipe(res);
// Second try - unsuccessful
request(options, function (err, response, body) {
var binaryData = body.toString('binary');
res.header('content-type', 'application/pdf');
res.send(binaryData);
});
});
Putting both data and binaryData in a console.log show that the proper data is there but the subsequent PDF that is downloaded is corrupt. I can't figure out why.
Wow, never mind. Found out Postman (Chrome App) was hijacking the request and response somehow. The // First Try example in my code excerpt works properly in browser.

Node.js and understanding how response works

I'm really new to node.js so please bear with me if I'm making a obvious mistake.
To understand node.js, i'm trying to create a webserver that basically:
1) update the page with appending "hello world" everytime the root url (localhost:8000/) is hit.
2) user can go to another url (localhost:8000/getChatData) and it will display all the data built up from the url (localhost:8000/) being triggered
Problem I'm experiencing:
1) I'm having issue with displaying that data on the rendered page. I have a timer that should call get_data() ever second and update the screen with the data variable that stores the appended output. Specifically this line below response.simpleText(200, data); isn't working correctly.
The file
// Load the node-router library by creationix
var server = require('C:\\Personal\\ChatPrototype\\node\\node-router').getServer();
var data = null;
// Configure our HTTP server to respond with Hello World the root request
server.get("/", function (request, response) {
if(data != null)
{
data = data + "hello world\n";
}
else
{
data = "hellow world\n";
}
response.writeHead(200, {'Content-Type': 'text/plain'});
console.log(data);
response.simpleText(200, data);
response.end();
});
// Configure our HTTP server to respond with Hello World the root request
server.get("/getChatData", function (request, response) {
setInterval( function() { get_data(response); }, 1000 );
});
function get_data(response)
{
if(data != null)
{
response.writeHead(200, {'Content-Type': 'text/plain'});
response.simpleText(200, data);
console.log("data:" + data);
response.end();
}
else
{
console.log("no data");
}
}
// Listen on port 8080 on localhost
server.listen(8000, "localhost");
If there is a better way to do this, please let me know. The goal is to basically have a way for a server to call a url to update a variable and have another html page to report/display the updated data dynamically every second.
Thanks,
D
The client server model works by a client sending a request to the server and the server in return sends a response. The server can not send a response to the client that the client hasn't asked for. The client initiates the request. Therefore you cannot have the server changing the response object on an interval.
The client will not get these changes to the requests. How something like this is usually handled as through AJAX the initial response from the server sends Javascript code to the client that initiates requests to the server on an interval.
setTimeout accepts function without parameter which is obvious as it will be executed later in time. All values you need in that function should be available at the point of time. In you case, the response object that you are trying to pass, is a local instance which has scope only inside the server.get's callback (where you set the setTimeout).
There are several ways you can resolve this issue. you can keep a copy of the response instance in the outer scope where get_data belongs or you can move the get_data entirely inside and remove setTimeout. The first solution is not recommended as if getChatData is called several times in 1sec the last copy will be prevailing.
But my suggestion would be to keep the data in database and show it once getChatData is called.

Node.js: Reading a variable from another module returns wrong value

I'm new to Node.js. I just wrote an http server module, with a count variable that stores number of times the module has received an http request:
var http = require("http");
var count = 0; //no of requests so far
function start() {
function onRequest(request, response) {
console.log(count + ": Request received in Main Server");
count++;
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello! you are request no. " + count);
response.end();
}
http.createServer(onRequest).listen(8888);
console.log("Main Server has started.");
}
function getCount() {
return count;
}
exports.getCount = getCount;
exports.start = start;
Then I wrote another server, let's call it test.js that starts the server module, but at the same time listens to http requests on another port, let's say 8889. The test.js is supposed to show number of requests that server.js has served so far.
var http = require("http");
var server = require("./server");
server.start();
function onRequest(request, response) {
console.log("Request received in Test Server");
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello! Server app has served: " + server.getCount());
response.end();
}
http.createServer(onRequest).listen(8889);
console.log("Test Server has started.");
When I run test.js, and make requests to server.js (http://localhost:8888), it adds up to the count. (I get double requests each time which as I read somewhere is due to the fact that the browser sends another request to get favicon.ico, ok, fine, that is not my problem). My problem is that when I send a request to test.js (http://localhost:8889), I always get number of requests I have already made to server.js plus one extra! In ther words, if http://localhost:8888 shows me 1, http://localhost:8889 which reads the same value from my server module shows 2!
Anyone has a clue why it is like that?
Thanks in advance!
When you hit refresh from a browser, requests are usually(I believe always, in Chrome I know it is always, not as sure in other browsers) made in this order:
yourdomain.com/
Followed by
yourdomain.com/favicon.ico
So, you are displaying the count after the first request. And THEN your favicon is requested, which is incrementing the value of your count. If you're making requests from a browser you will NEVER see the same value in both windows, because your favicon request will always come in, before you are able to request your 8889 port. I guess, it is theoretically possible. If you could hit refresh on both windows within X number of milliseconds, you could ping 8889 before the favicon request, but if you're working from a local machine, this number of milliseconds would be so small as to be impossible.
If you want to validate this you could do a simple check like this:
if(request.url.match(/favicon.ico/i) === false) count++;
Which should keep your count from updating for favicon requests.

Resources