Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 664 Vote(s) - 3.43 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Redirect all trailing slashes globally in express

#1
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][1] 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

[1]:

[To see links please register here]

Reply

#2
The answers above will work in a lot of cases but GET vars can encounter issues and if you were to put that inside another express middleware its reliance on `req.path` will cause a problem and its reliance on `req.url` can also have unwanted side effects.
If you're looking for a tighter solution this will do the trick:

// Redirect non trailing slash to trailing slash
app.use(function(req, res, next){
// Find the query string
var qsi = req.originalUrl.indexOf('?');
// Get the path
var path = req.originalUrl;
if(qsi > -1) path = path.substr(0, qsi);
// Continue if the path is good or it's a static resource
if(path.substr(-1) === '/' || ~path.indexOf('.')) return next();
// Save just the query string
var qs = '';
if(qsi > -1) qs = req.originalUrl.substr(qsi);
// Save redirect path
var redirect = path + '/' + qs;
// Redirect client
res.redirect(301, redirect);

console.log('301 redirected ' + req.originalUrl + ' to ' + redirect);
});

It's always happy with GET variables and won't break if you were to put it inside middleware.
Reply

#3
The connect-slashes middleware was designed specifically for this need:

[To see links please register here]


Install it with:

`$ npm install connect-slashes`

Read the full documentation:

[To see links please register here]

Reply

#4
One liner:

router.get('\\S+\/$', function (req, res) {
return res.redirect(301, req.path.slice(0, -1) + req.url.slice(req.path.length));
});

This will only catch the url's that need to be redirected, and ignore the others.

Example results:

/ ==> /
/a ==> /a
/a/ ==> /a
/a/b ==> /a/b
/a/b/ ==> /a/b
/a/b/?c=d ==> /a/b?c=d
Reply

#5
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();
});
Reply

#6
I'm adding this answer because I had too many issues with other solutions.

````
/**
* @param {express.Request} req
* @param {express.Response} res
* @param {express.NextFunction} next
* @return {void}
*/
function checkTrailingSlash(req, res, next) {
const trailingSlashUrl = req.baseUrl + req.url;
if (req.originalUrl !== trailingSlashUrl) {
res.redirect(301, trailingSlashUrl);
} else {
next();
}
}

router.use(checkTrailingSlash);
````

This will translate:

/page ==> /page/
/page?query=value ==> /page/?query=value

Reply

#7
/**
* @param {express.Request} req
* @param {express.Response} res
* @param {express.NextFunction} next
* @return {void}
*/
function checkTrailingSlash(req, res, next) {
if (req.path.slice(req.path.length-1) !== '/') {
res.redirect(301, req.path + '/' + req.url.slice(req.path.length));
} else {
next();
}
}

app.use(checkTrailingSlash);

Example results:

/ ==> /
/a ==> /a/
/a/ ==> /a/
/a/b ==> /a/b/
/a/b/ ==> /a/b/
/a/b?c=d ==> /a/b/?c=d
/a/b/?c=d ==> /a/b/?c=d
Reply

#8
If you use [fastify][1] to deal with your routes, you can try setting Fastify's ignoreTrailingSlash option to true.

const fastify = require('fastify')({
ignoreTrailingSlash: true
})


[1]:

[To see links please register here]

Reply

#9
[The answer][1] by [Tolga Akyüz](

[To see links please register here]

) 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.slice(-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](

[To see links please register here]

) and stated in [RFC 1738](

[To see links please register here]

), 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](

[To see links please register here]

), a double slash `//` in the beginning of the path causes a dangerous redirection. For example the URL `http://example.com//evil.example/` creates a redirect to `//evil.example` that is interpreted as `http://evil.example` or `https://evil.example` by the victim's browser. Also, noted by [Van Quyet](

[To see links please register here]

), 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](

[To see links please register here]

). Additionally, the code syntax was updated to ES6.

[1]:

[To see links please register here]

Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through