I was playing around with node.js and something strange happens when you run this code:
var http = require("http");
var i = 0;
function onRequest(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("You're number " + i++);
response.end();
}
http.createServer(onRequest).listen(8888);
I would expect it to behave like a page views counter, but with each refresh of the browser tab i get the result of what seems to be i=i+2 instead of a simple increment. Could someone explain this behavior to me?
Your browser is hitting your server for favicon.ico as well. Each request increments i, and the request for favicon.ico counts.
Use a tool such as Fiddler or WireShark to see this behavior yourself.
I bet it's the favicon request that browsers love to send over and over again.
Related
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?
I am following along with the tutorials on The New Boston from Bucky and cant seem to get images to show up in the HTML file running a simple static index page in node.js
please note: this is a school project, I am tasked with doing this without using middle-ware such as express or connect which we have not reached yet. :D
var http = require('http');
var fs = require('fs');
var accessTime = new Date();
var accessCount = 0;
function send404Response(response) {
response.writeHead(404, {"Content-Type": "text/plain"});
response.write("Error 404: Page not found!");
response.end();
}
function onRequest(request, response) {
if (request.method == 'GET' && request.url == '/' ){
response.writeHead(200, {"Content-Type": "text/html"});
fs.createReadStream("./index.html").pipe(response);
fs.writeFileSync("logfile.txt", "\n Someone has accessed the index page \n" + accessTime + "\n ", "UTF-8",{'flags': 'a'});
console.log("A user made a request");
accessCount += 1;
console.log(accessCount + " page requests so far . . .");
}else {
send404Response(response);
}
}
http.createServer(onRequest).listen(8888);
console.log("Server is running...");
When I run it, the html page loads fine as localhost:8888 but no images will show up unless I use external images. for example the html would just have standard image tags?
<img src='photo.jpg' .... /> // doesnt work
<img src='http://www.AWebSite.com/photo.jpg' .... /> // naturally works
Thanks!!
Right, so at the moment you're not providing a code path for the images. Your first code block responds to 'http://localhost:8888/' and nothing else; you wouldn't even serve 'http://localhost:8888/index.html' if someone requested it.
If you want to serve all static content, then there's a few ways to go about it. To be the most web server-like, you'd probably start off by having a known folder with your static assets (e.g. ./public). Then you'd want to just take request.url and look for that under the public path using fs.stat(). If that path exists in that location, then you'd check the file extension to figure out the Content-Type header and serve it like you're doing now. If not, then you'd return a 404 like you are currently doing.
If you're not allowed to use third party libraries at all, I'd also recommend chunking each logical bit into its own file that you can require. If you can use third party libraries (just not middleware), then I'd say look into async.js to help the file handling workflow a bit, and to avoid callback hell.
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);
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.
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.