无序搜索参数作为节点中的URL路径组件

时间:2016-07-23 11:14:23

标签: javascript node.js express

有没有人知道如何定义快速路线(或极少数路线)以无特定顺序接收搜索参数?

我说的是有一些搜索参数,例如电影细节:

  • 名称(例如“foo”)
  • 年(例如2015年)
  • 类型(例如“喜剧”)
  • 类型(例如“电影”,“系列”,“插曲”)
  • 季节(例如1)
  • 剧集(例如1)

并且能够在单个URL中获取输入,例如

/search/name/foo/genre/action

或同等地:

/search/year/2016/season/5/episode/12/name/bar

我不想强制命令这些参数,因为只知道部分信息(即不是每个参数的值),我不想强​​迫用户必须知道给定的顺序最终会有很多搜索参数。

我对此有两个想法...

(1)使用express的app.use指定一些重复模式可能类似于:

/\/search\/(([name|year|type|genre|season|episode])\/(.*))+

然后以某种方式访问​​捕获的组中的路由处理函数

中的参数名称和值

(2)使用express的app.param来定义搜索参数的参数,例如

/search/:searchParam/:searchValue

但我不确定如何表明这些可能会重复,并且在param处理函数中你似乎只能访问由param本身表示的值,而不是相邻或相关的param值,例如

app.param('searchParam', function(req,res,next,searchParam) {
  var paramRegex = new RegExp('name|year|type|season|episode|genre', i);

  if( !paramRegex.test(searchParam) ) {
    res.status(400)
       .send('URL component for "searchParam" must be like: "'+ paramRegex + '" (got:  "'+ searchParam + '")');
  } else {
    var query = req.query || {};

    query[searchParam] = '???'; // no way to access :searchValue here from what I can see?

    req.query = query;

    next();
  }
});

之前有人遇到过这个问题,除了像(1)这样的东西之外,还有更优雅的方式去做我喜欢的事吗?

更新#1:

唉!很讨厌地狱:(

事实证明,你不能在JS中使用带有量词的捕获组 - 它只会捕获 最后 捕获组的值(按照{{ 3}} post)。

所以我试图用这个:

router.get( /^\/search(?:\/(name|year|type|season|episode|genre)\/(.*?))*$/i, search );

其中search只是:

function search(req,res) {  
  console.log('Params: ', req.params);
}

当我尝试访问此网址时:

.../search/year/2016/season/2/episode/12

我在控制台中得到什么?:

Params:  { '0': 'episode', '1': '12' }

仅限最后匹配组的值。看起来我只需要接受整个URL并“手动”解析它。

1 个答案:

答案 0 :(得分:0)

好的,所以终于有机会再看一下这个了,并想出办法做我原本打算做的事情(虽然我可能会或者可能不会实际使用它,可能会选择查询字符串代替)。 但如果您确实觉得这很有用,请给它投票 - 非常感谢!

这就是我的所作所为:

(1)在我的快递路由器上为我的动态搜索网址设置路线(与原始问题相同,我没有更改此部分):

router.get( /^\/search(?:\/(name|year|type|season|episode|genre)\/(.*?))+$/i, 
            search );

(2)更新了引用的search函数,如下所示:

function search(req,res) {  
  console.log('URL: ' + req.url);

  var allParamsStr = req.url.match(/^\/search(\/.*)$/i);
  console.log('All parameters string: ' + allParamsStr[1]);

  var singleParamStr = allParamsStr[1].match(/(\/(?:name|year|type|season|episode|genre)\/\w+)/gi);
  console.log('Single parameter strings: ' + JSON.stringify(singleParamStr,null,2));

  for( var i = 0; i < singleParamStr.length; i++ ) {
    var params = singleParamStr[i].match(/^\/(name|year|type|season|episode|genre)\/(\w+)$/i);
    console.log('Parameter (key,value): (' + params[1] + ',' + params[2] + ')');
  }    
}

(3)通过在以下URL上发出GET请求来测试它:

/search/year/2009/season/5/episode/10/genre/comedy

(4)我从控制台得到以下输出:

URL: /search/year/2009/season/5/episode/10/genre/comedy
All parameters string: /year/2009/season/5/episode/10/genre/comedy
Single parameter strings: [
  "/year/2009",
  "/season/5",
  "/episode/10",
  "/genre/comedy"
]
Parameter (key,value): (year,2009)
Parameter (key,value): (season,5)
Parameter (key,value): (episode,10)
Parameter (key,value): (genre,comedy)