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
A 301 redirect is the best way to resolve duplicate content issues caused by trailing slashes. If you're just fixing one page, you'd redirect the duplicate copy to the version that matches your chosen URL structure. Most trailing slash issues however, affect many pages across a website.
app. use((req, res, next) => { //next() or return next() }); In the function app. use((req, res, next), we have three callbacks i.e. request, response and next. So, if you want to use next() then simply write next() and if you want to use return next then simply write return next().
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.
Historically, a trailing slash marked a directory and a URL without a trailing slash at the end used to mean that the URL was a file. Today, however, trailing slashes are purely conventional, and Google does not care whether you use them; as long as you're consistent.
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 fixes the problem by adding the original query to the end of the redirect destination url. The version also has a few safety features described in the update notes.
app.use((req, res, next) => { if (req.path.substr(-1) === '/' && req.path.length > 1) { const query = req.url.slice(req.path.length) const safepath = req.path.slice(0, -1).replace(/\/+/g, '/') res.redirect(301, safepath + query) } else { next() } })
Update 2016: 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.
Update 2021: As discovered by Matt, a double slash //
in the beginning of the path causes a dangerous redirection. For example the url http://example.com//evil.com/
creates a redirect to //evil.com
that is interpreted as http://evil.com
or https://evil.com
by the victim's browser. Also, noted by Van Quyet, there can be multiple trailing slashes that should be handled gracefully. Due to these findings, I added a line that safeguards the path by replacing all consequent slashes by a single /
. I trust the performance overhead caused by the safeguard to be negligible because the regexp literals are only compiled once. Additionally, the code syntax was updated to ES6.
Try adding a middleware for that;
app.use((req, res, next) => { const test = /\?[^]*\//.test(req.url); if (req.url.substr(-1) === '/' && req.url.length > 1 && !test) res.redirect(301, req.url.slice(0, -1)); else next(); });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With