Redirect all trailing slashes globally in express

匿名 (未验证) 提交于 2019-12-03 02:11:02

问题:

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

回答1:

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


回答2:

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.



回答3:

The connect-slashes middleware was designed specifically for this need: https://npmjs.org/package/connect-slashes

Install it with:

$ npm install connect-slashes

Read the full documentation: https://github.com/avinoamr/connect-slashes



回答4:

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

router.use(function(req, res, next) {     if (req.originalUrl != req.baseUrl + req.url) {         res.redirect(301, req.baseUrl + req.url);     }     else         next(); }); 

This will translate:

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


回答5:

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 str
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!