快速redirect所有的尾部斜杠

我正在使用Node.js和Express,我有以下路由:

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

我在我的课程页面上有一个Disqus小部件,我注意到一个奇怪的行为,当去myapp.com/lessonsmyapp.com/lessons/我得到两个不同的页面(他们有一个评论,我以前在Disqus添加和另一个没有评论)。

有没有一种方法可以将我的所有url“封锁”为无斜线? 我试图添加strict routing标志来expression,但结果是一样的

谢谢

       

网上收集的解决方案 "快速redirect所有的尾部斜杠"

尝试添加一个中间件;

 app.use(function(req, res, next) { if(req.url.substr(-1) == '/' && req.url.length > 1) res.redirect(301, req.url.slice(0, -1)); else next(); }); 

TolgaAkyüz 的答案是鼓舞人心的,但如果斜线后面有任何字符则不起作用。 例如http://example.com/api/?q=a被redirect到http://example.com/api而不是http://example.com/api?q=a

下面是改进版本的中间件,通过将原始查询添加到redirect目标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(); } }); 

注意:正如jamesk所述,并在RFC 1738中指出,只有在域之后没有任何内容时,尾部斜线才能被省略。 因此, http://example.com?q=a : http://example.com/?q=a =a是无效的url,其中http://example.com/?q=a是有效的url。 在这种情况下,不应该进行redirect。 幸运的是,expression式req.path.length > 1负责处理这个问题。 例如,给定URL http://example.com/?q=a ,pathreq.path等于/ ,因此避免了redirect。

连接斜杠中间件是专门为此需要而devise的: https : //npmjs.org/package/connect-slashes

安装它:

$ npm install connect-slashes

阅读完整的文档: https : //github.com/avinoamr/connect-slashes

我添加了这个答案,因为我与其他解决scheme有太多的问题。

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

这将转化为:

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

上面的答案在很多情况下都可以使用,但是GETvariables可能会遇到问题,如果你把它放到另一个expression中间件里面,那么对req.path依赖会导致一个问题,并且它对req.url依赖也会产生不必要的副作用。 如果你正在寻求一个更紧密的解决scheme,这将有诀窍:

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

它总是对GETvariables感到满意,如果你把它放在中间件里,它不会中断。

一个class轮:

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

这只会捕捉需要redirect的url,而忽略其他url。

示例结果:

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