I am using Node.js and Express and I have the following routing :
app.get('/', function(req,res){
locals.date = new Date().toLocaleDateString();
res.render('home.ejs', locals);
});
function lessonsRouter (req, res, next)
{
var lesson = req.params.lesson;
res.render('lessons/' + lesson + '.ejs', locals_lessons);
}
app.get('/lessons/:lesson*', lessonsRouter);
function viewsRouter (req, res, next)
{
var controllerName = req.params.controllerName;
res.render(controllerName + '.ejs', locals_lessons);
}
app.get('/:controllerName', viewsRouter);
I have a Disqus widget on my lessons pages and I have noticed a strange behavior that when going to myapp.com/lessons
and myapp.com/lessons/
I get two different pages (on of them had a comment I previously added in Disqus and the other one doesn't have a comment).
Is there a way to "canonize" all of my urls to be without trailing slashes ? I have tried to add the strict routing
flag to express but the results were the same
Thanks
The answer by Tolga Akyüz is inspiring but doesn't work if there is any characters after the slash. For example http://example.com/api/?q=a
is redirected to http://example.com/api
instead of http://example.com/api?q=a
.
Here is an improved version of the proposed middleware that fix the problem by adding the original query to the end of the redirect destination url:
app.use(function(req, res, next) {
if (req.path.substr(-1) == '/' && req.path.length > 1) {
var query = req.url.slice(req.path.length);
res.redirect(301, req.path.slice(0, -1) + query);
} else {
next();
}
});
Note: As noted by jamesk and stated in RFC 1738, the trailing slash can only be omitted when there is nothing after the domain. Therefore, http://example.com?q=a
is an invalid url where http://example.com/?q=a
is a valid one. In such case, no redirection should be done. Fortunately, the expression req.path.length > 1
takes care of that. For example, given the url http://example.com/?q=a
, the path req.path
equals to /
and thus the redirection is avoided.