Redirecting from naked domain to www with node/express?

2,335 views
Skip to first unread message

Felix E. Klee

unread,
Jun 4, 2012, 3:07:09 AM6/4/12
to nodejs
I am hosting an express.js application on nodejitsu.com. Now, I have
assigned two domain names to it:

example.com
www.example.com

This works (although, this morning there were some glitches). Now, I
would like to always redirect:

example.com -> www.example.com
example.com/some/page.html -> www.example.com/some/page.html
...

Is there an easy way to achieve that using routing from within
node/express?

Alan Hoffmeister

unread,
Jun 4, 2012, 8:31:58 AM6/4/12
to nod...@googlegroups.com
I think that the correct way is to asign a CNAME for "www.example.com"
in your dns manager redirecting it to "example.com".

But yep, you can do this in express by writting a middleware that
detect the called host name and redirect the user if necessary.

You would be able to get more information at Express.js list:
https://groups.google.com/group/express-js

--
Alan Hoffmeister


2012/6/4 Felix E. Klee <felix...@inka.de>:
> --
> Job Board: http://jobs.nodejs.org/
> Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
> You received this message because you are subscribed to the Google
> Groups "nodejs" group.
> To post to this group, send email to nod...@googlegroups.com
> To unsubscribe from this group, send email to
> nodejs+un...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/nodejs?hl=en?hl=en

Felix E. Klee

unread,
Jun 4, 2012, 8:41:54 AM6/4/12
to nod...@googlegroups.com
On Mon, Jun 4, 2012 at 2:31 PM, Alan Hoffmeister
<alanhof...@gmail.com> wrote:
> I think that the correct way is to asign a CNAME for "www.example.com"
> in your dns manager redirecting it to "example.com".

Setting a CNAME should not make a difference to the current setup. I
already have identical A records for www.example.com and example.com.
And this works. What I want, though, is redirection.

> But yep, you can do this in express by writting a middleware that
> detect the called host name and redirect the user if necessary.

Thanks for the suggestion! Perhaps there is already a middleware that
does this.

Oliver Leics

unread,
Jun 4, 2012, 8:51:36 AM6/4/12
to nod...@googlegroups.com
It should be something like this:

express.use(function(req, res, next) {
if(req.headers.host === 'example.com') {
res.writeHead(303, {'Location': 'http://www.example.com'+req.url})
res.end()
}
})

I did not test this.
I'm not even using express :-D
But something like this should do the trick.
> --
> Job Board: http://jobs.nodejs.org/
> Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
> You received this message because you are subscribed to the Google
> Groups "nodejs" group.
> To post to this group, send email to nod...@googlegroups.com
> To unsubscribe from this group, send email to
> nodejs+un...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/nodejs?hl=en?hl=en



--
Oliver Leics @ G+
https://plus.google.com/112912441146721682527

Felix E. Klee

unread,
Jun 4, 2012, 9:43:05 AM6/4/12
to nod...@googlegroups.com
On Mon, Jun 4, 2012 at 2:51 PM, Oliver Leics <oliver...@gmail.com> wrote:
> It should be something like this:
>
> [...]

Thanks! It's similar to something I just found on GitHub:

https://github.com/nodejitsu/node-http-proxy/issues/37#issuecomment-1068224

(though, the reporter of the issue wants to do the opposite)

Felix E. Klee

unread,
Jun 4, 2012, 10:38:55 AM6/4/12
to nod...@googlegroups.com
On Mon, Jun 4, 2012 at 2:51 PM, Oliver Leics <oliver...@gmail.com>
wrote:
> express.use(function(req, res, next) {
> if(req.headers.host === 'example.com') {
> res.writeHead(303, {'Location': 'http://www.example.com'+req.url})
> res.end()
> }
> })

That made me learn a little about middleware, a new concept to me, and I
really like it. In the end I implemented basically what you proposed,
plus `next()` in the else clause.

Oliver Leics

unread,
Jun 4, 2012, 11:02:06 AM6/4/12
to nod...@googlegroups.com
Middleware is a huge word for such a small yet powerful interface.

And yes, the next() call was missing.

Most nodejs code does not use the else-clause, but early return
instead. Nicer to read, fewer to type and some benchmarks showed a
slight speed-improvement.

The code would then be like this:

express.use(function(req, res, next) {
if(req.headers.host === 'example.com') {
return res.send({'Location': 'http://www.example.com'+req.url}, 301)
}
next()
})

This should be the shortest implementation according to
http://expressjs.com/guide.html
and .send() of express.

Tim Caswell

unread,
Jun 4, 2012, 11:07:14 AM6/4/12
to nod...@googlegroups.com
I will mention that most browsers send the port as part of the host header.  So if you're testing locally using a custom /etc/hosts on port 8080 (or just using port 8080 on the production machine), you'll need to account for that in the host routing.

Felix E. Klee

unread,
Jun 4, 2012, 11:10:14 AM6/4/12
to nod...@googlegroups.com
On Mon, Jun 4, 2012 at 5:07 PM, Tim Caswell <t...@creationix.com> wrote:
> So if you're testing locally [...]

Thanks for the suggestion. But that's not necessary: The code is for
production only, with the if clause checking the domain.

Felix E. Klee

unread,
Jun 4, 2012, 11:12:45 AM6/4/12
to nod...@googlegroups.com
On Mon, Jun 4, 2012 at 5:02 PM, Oliver Leics <oliver...@gmail.com>
wrote:
> Nicer to read,

Matter of taste.

> fewer to type and some benchmarks showed a slight speed-improvement.

Well, I guess this can be optimized with tools such as the Closure
Compiler.

> express.use(function(req, res, next) {
> if(req.headers.host === 'example.com') {
> return res.send({'Location': 'http://www.example.com'+req.url}, 301)
> }
> next()
> })

Thanks!

Oliver Leics

unread,
Jun 4, 2012, 11:50:49 AM6/4/12
to nod...@googlegroups.com
On Mon, Jun 4, 2012 at 5:07 PM, Tim Caswell <t...@creationix.com> wrote:
> I will mention that most browsers send the port as part of the host header.

Good point. I'm not sure if this is the case for port 80 too, but
let's stay on the save side:

express.use(function(req, res, next) {
if(req.headers.host.split(':',1)[0] === 'example.com') {
return res.send({'Location': 'http://www.example.com'+req.url}, 301)
}
next()
})

And what about case sensitivity?

if(req.headers.host.split(':',1)[0].toLowerCase() === 'example.com')

-o

Felix E. Klee

unread,
Jun 4, 2012, 11:54:21 AM6/4/12
to nod...@googlegroups.com
Updated:

if (req.headers.host.split(':', 1)[0].toLowerCase() ===
'example.com') {
res.header('Location', 'http://www.example.com' + req.url);
return res.send(301);
}
next();

Felix E. Klee

unread,
Oct 9, 2012, 3:50:55 PM10/9/12
to nod...@googlegroups.com
On Tue, Oct 9, 2012 at 7:45 AM, Anthony Ettinger <etti...@gmail.com>
wrote:
> I just created a module to do domain redirecting on npm:
> https://npmjs.org/package/express-force-domain

Cool!

Isaac Schlueter

unread,
Oct 9, 2012, 4:12:07 PM10/9/12
to nod...@googlegroups.com
You can also use canonical-host for this:

https://npmjs.org/package/canonical-host

var canon = require("canonical-host")('https://hostname.com')
app.use(canon)

It also supports specific port numbers, https/http, etc. That's what
I'm using to redirect npm.im to npmjs.org.

Felix E. Klee

unread,
Oct 10, 2012, 10:21:06 AM10/10/12
to nod...@googlegroups.com
On Tue, Oct 9, 2012 at 10:12 PM, Isaac Schlueter <i...@izs.me> wrote:
> You can also use canonical-host for this: [...]

Thanks! It's good to know the options.

CoolAJ86

unread,
Oct 10, 2012, 2:13:55 PM10/10/12
to nod...@googlegroups.com
var nowww = require('nowww');

connect.use(nowww);

I believe `express.use(nowww);` should work the same.



https://npmjs.org/package/nowww

CoolAJ86

unread,
Oct 10, 2012, 2:14:48 PM10/10/12
to nod...@googlegroups.com
typo. should be

connect.use(nowww())
Reply all
Reply to author
Forward
0 new messages