6

I'm trying to do URL rewriting in Express JS 4. Everything I read says that I should be able to overwrite the request.url property in middleware. The two existing Node modules that do rewrite use this method. However, when I try to do this:

app.use('/foo', function(req, res){
    var old_url = req.url;
    req.url = '/bar';

    console.log('foo: ' + old_url + ' -> ' + req.url);
});

app.get('/bar', function(req, res) {
    console.log('bar: ' + req.url);
});

it just doesn't work.

One note that might help: it appears that req.url above always is / regardless of the actual URL used. Did Express 4 change how the URL is maintained, and not update their documentation? How do I accomplish URL rewriting in Express 4?

Jason Brubaker
  • 163
  • 1
  • 2
  • 7

3 Answers3

12

If you want processing to continue after your change, you have to call next() in your middleware to keep the processing going on to other handlers.

app.use('/foo', function(req, res, next){
    var old_url = req.url;
    req.url = '/bar';

    console.log('foo: ' + old_url + ' -> ' + req.url);
    next();
});

The doc for req.originalUrl says this:

This property is much like req.url; however, it retains the original request URL, allowing you to rewrite req.url freely for internal routing purposes. For example, the “mounting” feature of app.use() will rewrite req.url to strip the mount point.

Which certainly implies that you can change req.url to change the routing.


Related answer:Rewrite url path using node.js

Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • 1
    Thanks for the help. There seemed to be two issues: one, that I didn't call next(), and two, that I didn't realize that `use('/foo', ...)` would pull the `/foo` off of the request.url. – Jason Brubaker Mar 13 '15 at 17:33
  • You can also create a completely separate router and mount it. Like: `controller.js`: `var router = require('express').Router; router.get('/ur', handle);, router.post('/foo', handle);router.use('/bar', handle);` Then in the `app.js`: `var ctrl = require('./controller'); app.use('/top-level-url', ctrl);` – Zlatko Mar 14 '15 at 00:49
1

If you use routers, the best solution is to use

req.url = '/new-url/';
app.handle(req, res, next);

See more on this gist

0

Rewriting req.url doesn't work with app.use(...) for some reason. (Express 4.17.1)

Use app.get(...) instead:

// this doesn't work
app.use('/foo', function(req, res, next){
  req.url = '/bar';
  next()
});

// this works
app.get('/foo', function(req, res, next){
  req.url = '/bar';
  next()
});
luff
  • 3,334
  • 1
  • 18
  • 9