快速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/lessons
和myapp.com/lessons/
我得到两个不同的页面(他们有一个评论,我以前在Disqus添加和另一个没有评论)。
有没有一种方法可以将我的所有url“封锁”为无斜线? 我试图添加strict routing
标志来expression,但结果是一样的
谢谢
尝试添加一个中间件;
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