我需要为将接受数组的get创建url,如何在node.js/express从请求中提取数组? 我需要传递带有我需要从 Person 返回的参数名称的数组
model.
/api/person # here I need to pass which fields I want to see but to be generic.
一种选择是使用 JSON 格式。
http://server/url?array=["foo","bar"]
服务器端
var arr = JSON.parse(req.query.array);
或您自己的格式
http://server/url?array=foo,bar
服务器端
var arr = req.query.array.split(',');
Express 在请求 URL 中多次重复查询参数时,将查询参数公开为数组:
app.get('/', function(req, res, next) {
console.log(req.query.a)
res.send(200)
}
GET /?a=x&a=y&a=z:
// query.a is ['x', 'y', 'z']
这同样适用于其他方法中的 req.body。
您可以以百分比编码对数组进行编码,只需"覆盖"字段,正式连接值即可。
app.get('/test', function(req,res){
console.log(req.query.array);
res.send(200);
});
localhost:3000/test?array=a&array=b&array=c
此查询将打印['a','b','c']
。
使用下一个代码:
app.use('/', (req, res) => {
console.log(req.query, typeof req.query.foo, Array.isArray(req.query.foo));
res.send('done');
});
在后端,您有两种标准方法。对于下一个请求:
/?foo=- 1&foo=2 /?foo[]=
- 1&foo[]=2
您的 NodeJS 后端将收到下一个查询对象:
- { foo: [ '1', '2' ] } 'object' true
- { foo: [ '1', '2' ] } 'object' true
因此,您可以选择所需的方式。我的建议是第二个,为什么?如果你需要一个数组,而你只传递一个值,那么选项一会将其解释为常规值(字符串),而不是数组。
[我说我们有两个标准,不行,url 中的数组没有标准,这是存在的两种常见方式。每个Web服务器都以自己的方式完成,如Apache,JBoss,Nginx等。
如果你想从 url 参数传递数组,你需要遵循下面的例子:
网址示例:
https://website.com/example?myarray[]=136129&myarray[]=137794&myarray[]=137792
要从快递中检索它:
console.log(req.query.myarray)
[ '136129', '137794', '137792' ]
Express有一个工具来检查您的路径是否与您正在创建的路线匹配:Express.js路线测试器。
正如Jose Mato所说,你必须决定如何构建你的网址:
- ?foo=1&foo=2
- ?foo[]=1&foo[]=2
如果选择方法 1,则 http 请求应如下所示:
http://baseurl/api/?foo=1&foo=2
您的路由应具有以下逻辑:
app.get('/api/:person', (req, res) => {
/*This will create an object that you can iterate over.*/
for (let foo of req.params.foo) {
/*Do some logic here*/
}
});
你可以传递用斜杠分隔的数组元素 - 获取/api/person/foo/bar/...
将路由定义为'/api/person/(:arr)*'
req.params.arr
将具有第一个参数。req.params[0]
将其余部分作为字符串。 您拆分并创建一个包含这两个的数组。
app.get('/api/person/(:arr)*', function(req, res) {
var params = [req.params.arr].concat(req.params[0].split('/').slice(1));
...
});
GET /api/person/foo
params = ["foo"]
GET /api/person/foo/bar
params = ["foo", "bar"]
。
在这里使用它,'%2C' 是逗号的 HTML 编码字符。
jsonToQueryString: function (data) {
return Object.keys(data).map((key) => {
if (Array.isArray(data[key])) {
return encodeURIComponent(`${key}=${data[key].map((item) => item).join('%2C')}`);
}
return encodeURIComponent(`${key}=${data[key]}`);
}).join('&');
}
访问查询参数
const names = decodeURIComponent(req.query.query_param_name);
const resultSplit = names.split(',');
当数组参数只包含一个值时会出现问题,因为那样它的行为就像一个简单的字符串。或者当它不包含任何值时。
例如:
- ?arrayParam=5
- ? ?arrayParam=
- 5&arrayParam=6
这是一个函数,它总是将具有给定名称的参数提取为数组:
export function extractArrQueryParams(
req: express.Request,
paramName: string
) {
let param = req.query[paramName];
let returnArray = [];
if (Array.isArray(param)) {
for (let e of param) {
returnArray.push(e);
}
} else {
if (param) {
returnArray.push(param);
}
}
return returnArray;
}
Express 可以使用 Node 的querystring
解析器或qs
来解析查询字符串。让我们来看看可能性。
字符串中重复的查询参数
您可以使用重复的查询参数来获取另一端的数组。它适用于节点可能使用的两个解析器:
> querystring.parse('a=b&a=c')
[Object: null prototype] { a: [ 'b', 'c' ] }
> qs.parse('a=b&a=c')
{ a: [ 'b', 'c' ] }
缺点
Byh 使用此方法,最终可能会得到数组(如果查询参数重复)或字符串(如果查询参数只出现一次):
> querystring.parse('a=b&a=c')
[Object: null prototype] { a: [ 'b', 'c' ] }
> querystring.parse('a=b')
[Object: null prototype] { a: 'b' }
数组的显式qs
表示法
qs
解析器(Node 将其用作默认 IIUC)提供了更明确的表示法,以确保该值将是一个数组。这些表示法是:
- 括号表示法:
> qs.parse('a[]=b&a[]=c') { a: [ 'b', 'c' ] }
- 索引表示法(如生成
{a: [1, 2]}
a[1]='d'&a[0]='c'
)> qs.parse('a[1]=c&a[0]=b') { a: [ 'b', 'c' ] }
(有更多可能性,但这些可能性需要更多的工作来设置,并且默认情况下不启用。
这些很棒,因为它们确保如果只有一个值存在,该值将是一个数组,而重复参数则不是这种情况:
> qs.parse('a[]=b')
{ a: [ 'b' ] }
> qs.parse('a=b')
{ a: 'b' }
缺点
这些符号都不适用于querystring
:
> querystring.parse('a[]=b')
[Object: null prototype] { 'a[]': 'b' }
总结
因此,您可以:
- 使用重复的查询参数与任何解析器一起使用,但如果查询参数给定一次,则不会为您提供数组;或
- 对数组使用
qs
语法,这将确保您获得数组但不适用于querystring
。
所有这些都记录在某个地方吗?
querystring
文档中有一个示例,其中重复的值变成了数组:
例如,查询字符串
'foo=bar&abc=xyz&abc=123'
解析为:{ foo: 'bar', abc: ['xyz', '123'] }
qs
文档中没有提到重复的查询参数,除非在字符串化时。然而,我测试了重复的查询参数,它产生了一个数组:
> qs.parse('a=b&a=c')
{ a: [ 'b', 'c' ] }