ExpressJS路由器归一化/规范的URL

我是用ExpressJS服务器为SPA提供标准/规范的URL。

虽然它是由服务器端路由器备份的SPA – 模板可能会有所不同,为应用程序的URL。 其中一个区别是<link rel="canonical" href="https://example.com{{ originalPath }}">标签。 不是相关的细节,但解释了问题的背景。 我预计只有一个url会有200个响应,它的变化将被redirect到301/302(适用于人类和search引擎)。

我想要使​​URL大小写敏感和严格(没有额外的斜杠),类似于Router选项,但非规范的url(不同的情况下或额外的斜线)应该做301/302redirect到规范的URL而不是404。

在大多数应用程序中,我只是想强制*路线的url是小写(除了查询),没有额外的斜线。 即app.all('*', ...) ,和redirect是:

 /Foo/Bar/ -> /foo/bar /foo/Bar?Baz -> /foo/bar?Baz 

但是,如果路线是明确定义的,则可能会有例外。 例如,有骆驼路线:

 possiblyNestedRouter.route('/somePath')... possiblyNestedRouter.route('/anotherPath/:Param')... 

所有非规范的URL都应该redirect到规范(参数大小写保持不变):

 /somepath/ -> /somePath /anotherpath/FOO -> /anotherPath/FOO 

规范URL背后的逻辑非常简单,所以在ExpressJS这个主题上我找不到任何东西。

做这个的最好方式是什么? 有没有中间件可以帮忙?

我已经找了npms,找不到任何东西,所以这就让我挠了脑子,而且我已经为每个请求编写了一个express的小任务,这似乎工作的很好。 请将此添加到您的代码。

 var urls = { '/main' : '/main', '/anotherMain' : '/anotherMain' } app.use(function(req, res, next){ var index = req.url.lastIndexOf('/'); //We are checking to see if there is an extra slash first if(req.url[index+1] == null || req.url[index+1] == undefined || req.url[index+1] == '/'){ //slashes are wrong res.send("please enter a correct url"); res.end(); }else{ for(var item in urls){ if(req.url != item && req.url.toUpperCase() == item.toUpperCase()){ res.redirect(item); console.log("redirected"); //redirected }else if (req.url == item) { console.log("correct url"); next(); }else{ //url doesn't exist } } } next(); }); app.get('/main', function(req, res){ res.render('mainpage'); }); app.get('/anotherMain', function(req, res){ res.send("here here"); }); 

用法

所有你需要做的就是,像上面所做的那样,将urls添加到urls对象,并赋予它相同的键值。 而已。 看看它是多么容易。 现在,您的所有客户请求都将被redirect到正确的页面。

UPDATE

我也做了一个POST请求,我认为这是相当准确的,你也应该试试看。 如果你想在用户混合斜杠的时候redirect,你需要为它写一些regex 。 我没有时间,我的大脑被炸,所以我做了一个简单的。 你可以改变它,只要你喜欢。 每个networking结构都有自己的一套规则。

 var urlsPOST = { '/upload' : '/upload' } app.use(function(req, res, next){ if(req.method == 'POST'){ var index = req.url.lastIndexOf('/'); if(req.url[index+1] == null || req.url[index+1] == undefined || req.url[index+1] == '/'){ //slashes are wrong res.sendStatus(400); res.end(); return false; }else{ for(var item in urlsPOST){ if(req.url != item && req.url.toUpperCase() == item.toUpperCase()){ res.redirect(307, item); res.end(); return false; //redirected }else if (req.url == item) { console.log("correct url"); next(); }else{ res.sendStatus(404).send("invalid URL"); return false; //url doesn't exist } } } } next(); }); 

您可能想要为此编写自己的中间件,大致如下:

 app.set('case sensitive routing', true); /* all existing routes here */ app.use(function(req, res, next) { var url = find_correct_url(req.url); // special urls only if(url){ res.redirect(url); // redirect to special url }else if(req.url.toLowerCase() !=== req.url){ res.redirect(req.url.toLowerCase()); // lets try the lower case version }else{ next(); // url is not special, and is already lower case }; }); 

使用与@ user8377060相同的代码,只需使用正则expression式即可。

  // an array of all my urls var urls = [ '/main', '/anotherMain' ] app.use(function(req, res, next){ var index = req.url.lastIndexOf('/'); //We are checking to see if there is an extra slash first if(req.url[index+1] == null || req.url[index+1] == undefined || req.url[index+1] == '/'){ //slashes are wrong res.send("please enter a correct url"); res.end(); }else{ for(var item in urls){ var currentUrl = new RegExp(item, 'i'); if(req.url != item && currentUrl.test(item)){ res.redirect(item); console.log("redirected"); //redirected }else if (req.url == item) { console.log("correct url"); next(); }else{ //url doesn't exist } } } next(); });