有没有人知道如何定义快速路线(或极少数路线)以无特定顺序接收搜索参数?
我说的是有一些搜索参数,例如电影细节:
并且能够在单个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并“手动”解析它。
答案 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)