Reputation: 11
I am testing the below code:
const http = require('http');
const server = http.createServer((req, res)=> {
const url = req.url;
if(url === '/'){
setTimeout(() => {
res.write('<html>');
res.write('<head><title>Enter Message</title></head>');
res.write('<body><form action="/message" method="POST"><input type="text" name="message"><button type="submit">Send</button></form></body>');
res.write('</html>');
return res.end();
}, 10000);
console.log('Hi');
}
});
server.listen(3000);
Scenario 1: What i do is i open a browser window and run localhost:3000, Hi is printed right away and after 10 seconds response is received in browser, meanwhile (between printing Hi in console and response is received in browser tab), i open a different browser tab and go to loaclhost:3000 again, i am expecting 'Hi' to be printed again, however it is only printed after the response has been received in first tab.
Scenario 2: I repeat the same as above however in the place of opening 2nd tab in same browser window i choose to open it in incongnito or on a device in the same network as my laptop, then i do not see any delay, Hi is printed right away for the request from incongnito window while the response for the 1st browser was still due to get received?
What am i missing here to understand? How can this behaviour be fixed?
Upvotes: 0
Views: 288
Reputation: 707328
What am i missing here to understand?
This is caused by the browser, not by node.js and is an implementation detail of the browser. The browser is apparently deciding that if there is already a request for http://localhost:3000
in process already, it won't send another identical request until that one finishes. You have verified that using a different browser makes the issue disappear which is consistent with this being a browser implementation issue/feature. Further, there is no behavior in node.js that would cause this because you are using setTimeout()
, so node.js is certainly free to begin processing the second request if it arrived.
If you can run some sort of network spy on either the client or server computers, you can verify the precise timing of when the second http request is sent, but I'm pretty sure you will find that the browser isn't sending it until the first request finishes.
I can think of three possible reasons why a browser might do this:
How can this behavior be fixed?
In previous tests a little while ago, I was able to work around it by adding a query string to the second request such as http://localhost:3000?num=2
which makes it a "different" request than the first one and the browser didn't hold it back. You would have to make sure your server was still processing the request even if it had a query string on it.
After Some Testing in Chrome
And, using a variant of your server code that strips off the query string so that it isn't influenced by that, I've verified that Chrome will hold off sending the second request until the first one finishes if the two browser windows have the exact same URL, but adding a query string to the second window will cause both to get sent immediately so that is a possible work-around.
Test in Firefox Yields Different Results
As more evidence that this has nothing to do with node.js itself, if I repeat the same test in the Firefox, there is no such behavior. Two identical requests in two separate windows are both sent to node.js one right after the other and I see the two console.log("Hi")
statements right away for both.
Upvotes: 4