我需要为 get 创建将接受数组的 url,如何在 node.js/express 从请求中提取数组?



我需要为将接受数组的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. 1&foo=2
  2. /?foo[]=
  3. 1&foo[]=2

您的 NodeJS 后端将收到下一个查询对象:

  1. { foo: [ '1', '2' ] } 'object' true
  2. { 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所说,你必须决定如何构建你的网址:

  1. ?foo=1&foo=2
  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' ] }

最新更新