149

How do I get a node.js server to redirect users to a 404.html page when they enter an invalid url?

I did some searching, and it looks like most results are for Express, but I want to write my server in pure node.js.

Damjan Pavlica
  • 31,277
  • 10
  • 71
  • 76
Dzung Nguyen
  • 9,152
  • 14
  • 65
  • 104
  • 1
    I used to believe that my app was better in pure node.js, but have been VERY happy after installing express. I can't imagine a node SPA/RESTful web service architecture without express now. – Graham Aug 16 '16 at 00:44
  • @Graham I had a question (What can standalone Express do?) to learn from precisely this type of experience you mention, but it was deleted. If you explain the extra functionality or benefits you gained from Express somewhere else, I'd be very interested to read it. – Nagev Jun 02 '22 at 10:35

9 Answers9

240

The logic of determining a "wrong" url is specific to your application. It could be a simple file not found error or something else if you are doing a RESTful app. Once you've figured that out, sending a redirect is as simple as:

response.writeHead(302, {
  'Location': 'your/404/path.html'
  //add other headers here...
});
response.end();
Chetan S
  • 23,637
  • 2
  • 63
  • 78
  • it doesn't show my 404 html page, maybe it's just show the header. – Dzung Nguyen Oct 31 '10 at 08:10
  • 8
    @Magic Not true. Try `Location: /` and it would redirect you to the root folder. – user3459110 Oct 24 '14 at 05:35
  • Agreed with Awal. I'm using `'Location': '/path/to/my/servers/content'` – Millie Smith May 01 '15 at 05:17
  • 1
    Thank you. I am running a static server and somehow installed Node without admin privileges. I don't have admin privileges on the PC, so I can't change the setup. Anyway, I managed to install Node.js without NPM or anything but the default packages, so I've been working hard to do everything using vanilla Node.js. Your technique let me set a dynamic port 80 forwarding script on my private IP to redirect all port 80 HTTP requests to whatever the port for the project I'm working on is. Thank you. Now, I'm just considering forwarding them to port 80 just for the fun of it. – 9pfs Mar 27 '21 at 20:50
88

If you are using ExpressJS, it's possible to use:

res.redirect('your/404/path.html');
Jay Wick
  • 12,325
  • 10
  • 54
  • 78
Daniël W. Crompton
  • 3,448
  • 25
  • 26
  • 91
    In express only. Not in native node.js app. – Sergey Yarotskiy Dec 03 '14 at 17:15
  • 1
    @TarunG Thanks for the comment, if you look at the edit history of the question you see that this wasn't always so clear. – Daniël W. Crompton Sep 06 '15 at 20:42
  • 3
    In my case res.redirect('/login') merely sends the login.html content in the response of the ajax call made. How do I rather open the page? – Tarun Oct 24 '16 at 20:03
  • Old post, but maybe you are looking for something like res.direct('http://localhost:5000/login'), especially if you're running your express server on a different port than your frontend like I happen to be. – jboxxx Oct 20 '19 at 19:46
19

To indicate a missing file/resource and serve a 404 page, you need not redirect. In the same request you must generate the response with the status code set to 404 and the content of your 404 HTML page as response body. Here is the sample code to demonstrate this in Node.js.

var http = require('http'),
    fs = require('fs'),
    util = require('util'),
    url = require('url');

var server = http.createServer(function(req, res) {
    if(url.parse(req.url).pathname == '/') {
        res.writeHead(200, {'content-type': 'text/html'});
        var rs = fs.createReadStream('index.html');
        util.pump(rs, res);
    } else {
        res.writeHead(404, {'content-type': 'text/html'});
        var rs = fs.createReadStream('404.html');
        util.pump(rs, res);
    }
});

server.listen(8080);
Chandra Sekar
  • 10,683
  • 3
  • 39
  • 54
17

404 with Content/Body

res.writeHead(404, {'Content-Type': 'text/plain'});                    // <- redirect
res.write("Looked everywhere, but couldn't find that page at all!\n"); // <- content!
res.end();                                                             // that's all!

Redirect to Https

res.writeHead(302, {'Location': 'https://example.com' + req.url});
res.end();

Just consider where you use this (e.g. only for http request), so you don't get endless redirects ;-)

Levite
  • 17,263
  • 8
  • 50
  • 50
6

Try this:

this.statusCode = 302;
this.setHeader('Location', '/url/to/redirect');
this.end();
Peanut
  • 3,753
  • 3
  • 31
  • 45
Mike
  • 69
  • 1
  • 1
  • 1
    This is probably an `Express` code snippet OP asked for pure `node.js` code – Refael Ackermann Oct 11 '16 at 17:44
  • 1
    It's not Express code. This looks like vanilla Node code except for the `this` part. In NodeJS you write a handler that accepts two parameters `(request, response)` and all those calls in the answer are on the `response` object. – AlexChaffee Nov 12 '18 at 20:09
6

I used a switch statement, with the default as a 404:

var fs = require("fs");
var http = require("http");

function send404Response (response){
    response.writeHead(404, {"Content-Type": "text/html"});
    fs.createReadStream("./path/to/404.html").pipe(response);
}

function onRequest (request, response){
    switch (request.url){
        case "/page1":
            //statements
            break;
        case "/page2":
            //statements
            break;
        default:
        //if no 'match' is found
            send404Response(response);
            break;
    }
}

http.createServer(onRequest).listen(8080);
Alon and Idan
  • 87
  • 1
  • 10
3

You have to use the following code:

response.writeHead(302 , {
           'Location' : '/view/index.html' // This is your url which you want
        });
response.end();
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
2

Use the following code this works fine in Native Nodejs

http.createServer(function (req, res) {
var q = url.parse(req.url, true);
if (q.pathname === '/') {
  //Home page code
} else if (q.pathname === '/redirect-to-google') {
  res.writeHead(301, { "Location": "http://google.com/" });
  return res.end();
} else if (q.pathname === '/redirect-to-interal-page') {
  res.writeHead(301, { "Location": "/path/within/site" });
  return res.end();
} else {
    //404 page code
}
res.end();
}).listen(8080);
-1

use

res.redirect('/path/404.html');

or you can redirect to any defined URI as

res.redirect('/');