ExpressJS路由器规范化/规范网址

时间:2017-02-11 19:10:30

标签: javascript node.js express routing

我正在使用ExpressJS服务器对SPA进行规范化/规范化网址。

虽然它是由服务器端路由器备份的SPA - 模板可能会因应用程序URL而有所不同。其中一个差异是<link rel="canonical" href="https://example.com{{ originalPath }}">标记。不是相关的细节,而是解释了问题的背景。我希望只有一个URL响应200,其变体被重定向到301/302(适用于活人和搜索引擎)。

我想使网址区分大小写和严格(没有额外的斜杠),类似于Router选项,但非规范网址(在大小写或额外斜线上有所不同)应该执行301/302重定向到规范网址而不是404。

在大多数应用程序中,我只想强制*路由的网址较低(查询除外),没有额外的斜杠。即app.all('*', ...),重定向是:

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

但如果明确定义了路由,则可能会有例外情况。例如,有骆驼路线:

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

所有非规范网址都应该重定向到规范(参数大小写完整):

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

规范网址背后的逻辑是非常简单的,所以我很难找到关于ExpressJS这个主题的任何内容。

最好的方法是什么?是否有中间件可以提供帮助?

3 个答案:

答案 0 :(得分:4)

我已经找到了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");
});

<强> USAGE

您只需将网址添加到urls对象,就像上面所做的那样,并为其提供相同的键值。就是这样。看它有多容易。现在,您的所有客户请求都将被重定向到正确的页面区分大小写

<强>更新

我还为POST请求做了一个,我认为它非常准确,你也应该尝试一下。如果您想要在用户混合斜杠时进行重定向,则需要为其编写一些regex。我也没有时间锻炼大脑,所以我做了一个简单的。你可以随意改变它。每个Web结构都有自己的一套规则。

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

答案 1 :(得分:1)

您可能希望为此编写自己的中间件,具体如下:

&#13;
&#13;
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
  };
});
&#13;
&#13;
&#13;

现在请记住,这个中间件可以放在所有当前路线之后,这样如果它与现有路线不匹配,您可以尝试查找它应该是什么。如果您使用不区分大小写的路由匹配,则需要在路由之前执行此操作。

答案 2 :(得分:0)

使用与@ user8377060相同的代码 只是用正则表达式。

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

  });
相关问题