Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

no request for favicon

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?

like image 415
mattdevio Avatar asked Jan 21 '16 08:01

mattdevio


1 Answers

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)
  • Chrome used to have a bug or might still have relating to favicon (Google please, there are many results)
  • Seems like browser caches favicon, force refresh and different methods used to make browser get the new/updated favicon, see here
  • I found that once Chrome browser is served the favicon then in the subsequent request, there is no more favicon request. Not until you change the 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:

enter image description here

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

enter image description here

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

enter image description here

Your issue could be related to

  1. Browser already has a cached favicon hence, does not request it
  2. You are not serving the favicon properly in server.js
  3. Something else

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

like image 107
Raf Avatar answered Sep 28 '22 04:09

Raf