Redirects With Express

May 14, 2019

The res.redirect() function lets you redirect the user to a different URL by sending an HTTP response with status 302. The HTTP client (browser, Axios, etc.) will then "follow" the redirect and send an HTTP request to the new URL as shown below.

const app = require('express')();

// The `res.redirect()` function sends back an HTTP 302 by default.
// When an HTTP client receives a response with status 302, it will send
// an HTTP request to the URL in the response, in this case `/to`
app.get('/from', (req, res) => {
  res.redirect('/to');
});
app.get('/to', (req, res) => res.send('Hello, World!'));

const server = await app.listen(3000);

const res = await axios.get('http://localhost:3000/from');
// Axios follows the redirect and sends a GET `/to` request, so the
// response will contain the string "Hello, World!"
res.data;

The res.redirect() function also lets you specify an HTTP status other than 302. The 302 status is considered a temporary redirect, which means search engines will still crawl the existing URL. If you want to indicate the URL has permanently changed, you should send a response with HTTP status 301.

const app = require('express')();

app.get('/from', (req, res) => {
  // The optional first parameter to `res.redirect()` is a numeric
  // HTTP status.
  res.redirect(301, '/to');
});
app.get('/to', (req, res) => res.send('Hello, World!'));

const server = await app.listen(3000);

const res = await axios.get('http://localhost:3000/from');
// "Hello, World!"
res.data;

Handling POST Requests

There's some nuances about which status code you should use for POST requests. Strictly speaking, HTTP 301 and 302 are not required to keep the same method and body content when redirecting. If you're redirecting a POST request, you should use HTTP 307 as a replacement for HTTP 302, and HTTP 308 as a replacement for HTTP 301.

const app = require('express')();
// Parser to set `req.body`
app.use(require('body-parser').json());

app.post('/from', (req, res) => {
  res.redirect(307, '/to');
});
app.post('/to', (req, res) => res.send(req.body.message));

const server = await app.listen(3000);

const res = await axios.post('http://localhost:3000/from', {
  message: 'Hello, World!'
});
// "Hello, World!"
res.data;

Here's a brief summary of the tradeoffs between these common redirect statuses.


More Express Tutorials