Search code examples
javascripthtmlnode.jsstatic-files

Node JS not serving the static image


I have already added the codes for serving an image on my node server but it seems to not serve images in the HTML when connecting to Node. I have also external CSS and JS that are being served correctly. Here is the fragment of my code in Node (See below). Thank you in advance!

var server = http.createServer(function(req, res) {
    var pathname = url.parse(req.url).pathname;
    var ext = path.extname(pathname);
    var handler = handlers[req.url];
    if(ext) {
        if(ext === ".css"){
            res.writeHead(200, { "Content-Type" : "text/css" });
        }
        else if(ext === ".js") {
            res.writeHead(200, { "Content-Type" : "text/javascript" });
        }
        else if(ext === ".jpg") {
            res.writeHead(200, { "Content-Type" : "image/jpg" });
        }
        res.write(fs.readFileSync(__dirname + pathname, "utf8"));
        res.end();
    }
    else if(handler) {
        handler(req, res);
    }
    else {
        res.writeHead(404, { "Content-type" : "text/plain" });
        res.end();
    }
});
server.listen(80);

Solution

  • I've seen a lot of questions like this on Stack Overflow when someone tries to implement their own static file server instead of using Express or something that works, and fails to make it work. If you can implement your own static file server then do it. If you can't, then it should be a sign that maybe it's not a good idea. Update: See below for solutions without Express.

    Problems

    Just by glancing at your code code I already see several serious problems with it, including:

    1. Your code is insecure - it allows anyone to get any file on your system.

    2. Your code is blocking - it will grind to a halt as soon as you get any concurrent connections.

    3. Your code doesn't work for binary files - only for text files, and only those with UTF-8 encoding

    4. Your code doesn't work for uppercase filenames, .jpeg extension etc.

    5. Your code doesn't serve HTML files correctly

    6. Your code crashes when files don't exist instead of responding with proper code

    Solution

    Anyone who answers a question like this has two options: either put a lot of effort and time into fixing every one of the problems mentioned above (which rarely happens because it is not a trivial task and that's why all you see are comments mentioning one or two of those problems instead of answers) or you can explain how the task should be done properly instead of adding countless fixes to something that was not a good idea in the first place.

    That having been said, what you can do to achieve your goal here in a secure and performant way is to put your static files (HTML, CSS, images etc.) into a directory, e.g. called html and use Express (or some other frameworks, see below) with a simple code like this:

    var path = require('path');
    var express = require('express');
    var app = express();
    
    var htmlPath = path.join(__dirname, 'html');
    
    app.use(express.static(htmlPath));
    
    var server = app.listen(80, function () {
        console.log('listening on port', server.address().port);
    });
    

    See the full example with explanation on GitHub:

    I put this example on GitHub because there are a lot of questions on Stack Overflow related to problems that people have with serving static files in Node. It's open-source, you can adapt it to your own needs and use in your code.

    For more info on Express, see:

    Other options

    Other frameworks that you can use to serve static files include:

    Without a framework

    If you still think that you don't want to use a high-level framework that does the job correctly and you want to roll your own solution, maybe for educational purposes, then see this answer:

    It explains how to serve static images with:

    1. express.static (express built-in middleware, like in this answer)
    2. express (express but without express.static)
    3. connect (one level below than express)
    4. http (using Node's http module)
    5. net (not even using http module)

    All of the examples posted are tested and work on Node versions 4, 5, 6 and 7.

    Other related answers: