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