Node.js server "404 not found" message to 404.html page

Problem

Im working with node.js and I would like to know how to display a 404.html instead of a "404 Not Found" message.

This is my server.js:

var http = require("http"),
url = require("url"),
path = require("path"),
fs = require("fs")
port = process.argv[2] || 8888;

http.createServer(function(request, response) {

var uri = url.parse(request.url).pathname
, filename = path.join(process.cwd(), uri);

path.exists(filename, function(exists) {
if(!exists) {
  response.writeHead(404, {"Content-Type": "text/plain"});
  response.write("404 Not Found\n");
  response.end();
  return;
}

if (fs.statSync(filename).isDirectory()) filename += 'public/Index/index.html';

fs.readFile(filename, "binary", function(err, file) {
  if(err) {        
    response.writeHead(500, {"Content-Type": "text/plain"});
    response.write(err + "\n");
    response.end();
    return;
  }

  response.writeHead(200);
  response.write(file, "binary");
  response.end();
  });
 });
}).listen(parseInt(port, 10));

console.log("Static file server running at\n  => http://localhost:" + port + "/\nCTRL + C to shutdown");

as you can see its just a static file server and I'm not using express.js or anything.

Problem courtesy of: user2539369

Solution

H i ,

within your 404 case

  response.writeHead(404, {"Content-Type": "text/plain"});
  response.write("404 Not Found\n");
  response.end();

You can change to

  response.writeHead(404, {"Content-Type": "text/html"});
  response.write(HTMLDATA);
  response.end();

'HTMLDATA' being either a string of HTML or a reference to a file you have gathered.

response.writeHead() is always set before the response.write().

Also see we have set the response type to 'text/html'


http://nodejs.org/api/http.html#http_class_http_serverresponse

Solution courtesy of: Rob Sedgwick

Discussion

This might be more of what you're looking for.

    fs.readFile('404.html', function(error, data) {
        res.writeHead(404, {'content-type': 'text/html'});
        res.end(data);
    });
Discussion courtesy of: Fizer Khan

Just load 404.html using fs.readFile and serve it with response.write

var http = require("http"),
url = require("url"),
path = require("path"),
fs = require("fs")
port = process.argv[2] || 8888;

http.createServer(function(request, response) {

var uri = url.parse(request.url).pathname
, filename = path.join(process.cwd(), uri);

path.exists(filename, function(exists) {
if(!exists) {
  fs.readFile('404.html', "binary", function(err, file) {
    if(err) {
       response.writeHead(404, {"Content-Type": "text/html"});
       response.write("404 Not Found\n");
    } else {
       response.writeHead(404);
       response.write(file, "binary");            
    }
    response.end();
    return;
  }
}

if (fs.statSync(filename).isDirectory()) filename += 'public/Index/index.html';

fs.readFile(filename, "binary", function(err, file) {
  if(err) {        
    response.writeHead(500, {"Content-Type": "text/plain"});
    response.write(err + "\n");
    response.end();
    return;
  }

  response.writeHead(200);
  response.write(file, "binary");
  response.end();
  });
 });
}).listen(parseInt(port, 10));

console.log("Static file server running at\n  => http://localhost:" + port + "/\nCTRL + C to shutdown");`enter code here`
Discussion courtesy of: Ilan Frumer

Do just for the 200... Read a file 404.html and write it to the response, just set the code 404 in writeHead.

Discussion courtesy of: farvilain
response.writeHead(404, {
  'Location': 'your/404/path.html'
  //add other headers here...
});
response.end();

or with a single line

response.redirect('your/404/path.html');
Discussion courtesy of: StarsSky

This recipe can be found in it's original form on Stack Over Flow.