I am writing a simple node.js file server using node's http module (I am not using EXPRESS).
I noticed my initial GET request is firing and all subsequent GET request are being made for the css and javascript; however, I am not getting a request for the favicon. Even when I look at at page inspector, I don't have any errors and the favicon is not showing up in the resources.
HTML
// Inside the head of index.html
<link rel="shortcut icon" href="img/favicon.ico" type="image/x-icon">
<link rel="icon" href="img/favicon.ico" type="image/x-icon">
node.JS
http.createServer(function(req, res){
// log each req method
console.log(`${req.method} request for ${req.url}`);
}).listen(3000)
There is a default icon that is a mustache, but not my custom icon. What am I missing here?
Just in case it's relevant to the question. I am using node v4.2.4
Edit
I think it has something to do with how I am reading and serving the file.
if ( req.url.match(/.ico$/) ){
var icoPath = path.join(__dirname, 'public', req.url);
var fileStream = fs.createReadStream(icoPath, "BINARY");
res.writeHead(200, {"Content-Type": "image/x-icon"});
fileStream.pipe(res)
Should I not be using a readstream? Is the encoding Binary or utf-8 or something else?
I played around with your repo code and did some changes to see if I can serve my favicon
or not. I found out some strange stuff:
favicon
serving is tricky and mysterious (my point of view) favicon
, force refresh and different methods used to make browser get the new/updated favicon
, see here
href
of favicon
in your html
file and that forces browser to make a fresh request. I copied bit/pieces of your code to reproduce the issue and got it working. I decided to serve the favicon
differently see below:
server.js
if(req.url.match("/requestFavicon") ){
var img = fs.readFileSync('public/favicon.ico');
res.writeHead(200, {'Content-Type': 'image/x-icon' });
res.end(img, 'binary');
}
index.html
<link rel="shortcut icon" type="image/x-icon" href="/requestFavicon"/>
Did a nodemon server.js
and used Chrome browser to make http://192.168.1.18:8080
request. The terminal
showed the following:
GET request for /
GET request for /requestFavicon
And the favicon.ico
(tiny vehicle .ico taken from here) displayed in the browser see below:
After the above favicon
was displayed, any subsequent http://192.1668.18:8080
produced no request for favicon
but, only displayed the following request in terminal of nodejs
GET request for /
Similarly no favicon
related request in the browser developer tool network tab.
At this point, I assumed that the browser has cached it and does not request at all because it already has it. So I googled and came across this SO question to force refresh favicon request. So, let's change the favicon
href in the index.html
(and server.js
) and retry
<link rel="shortcut icon" type="image/x-icon" href="/updatedRequestFavicon"/>
Now retry access http://192.168.1.18:8080
and watch for nodejs terminal as well as chrome developer console and I get the following:
GET request for /
GET request for /UpdatedRequestFavicon
Now I want to totally change the favicon
and put a new one. I added this one updated the server.js
and refreshed the browser. Surprisingly no console log in nodejs (for new favicon
), no request in browser developer tools newtork console (so served the cached value then).
To force the browser to get the new favicon
, I want to change the href
of favicon
in index.html
and and update the server.js
with new href and then see if brwoser gets forced to request for updated favicon or keep using the cached one.
<link rel="shortcut icon" type="image/x-icon" href="/NewFavicon"/>
if(req.url.match("/NewFavicon") ){
var img = fs.readFileSync('public/favicon_new.ico');
res.writeHead(200, {'Content-Type': 'image/x-icon' });
res.end(img, 'binary');
}
Changed. Changes reloaded by nodemon, refresh the browser and here is the result:
GET request for /
GET request for /NewFavicon
Your issue could be related to
If you want to test my code, feel free, here is the server.js
var http = require('http');
var fs = require('fs');
var path = require('path');
var server = http.createServer(function(req, res) {
// Log req Method
console.log(`${req.method} request for ${req.url}`);
//res.writeHead(200);
//res.end('index.html');
// Serve html, js, css and img
if ( req.url === "/" ){
fs.readFile("index.html", "UTF-8", function(err, html){
res.writeHead(200, {"Content-Type": "text/html"});
res.end(html);
});
}
if(req.url.match("/NewFavicon") ){
console.log('Request for favicon.ico');
var img = fs.readFileSync('public/favicon_new.ico');
res.writeHead(200, {'Content-Type': 'image/x-icon' });
res.end(img, 'binary');
//var icoPath = path.join(__dirname, 'public', req.url);
//var fileStream = fs.createReadStream(icoPath, "base64");
//res.writeHead(200, {"Content-Type": "image/x-icon"});
//fileStream.pipe(res);
}
});
server.listen(8080);
Here is index.html
<!DOCTYPE html>
<html>
<head>
<title>nodeCAST</title>
<link rel="shortcut icon" type="image/x-icon" href="/NewFavicon"/>
<!--<link rel="shortcut icon" href="img/favicon.ico" type="image/x-icon">
<link rel="icon" href="img/favicon.ico" type="image/x-icon">-->
</head>
<body>
<p>I am the index.html</p>
</body>
</html>
I placed the favicon.ico under /public directory. Good luck.
EDIT
Tested with Chrome Browser Version 47.0.2526.111 m
Node v4.2.4
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With