以前在项目里遇到过这个问题:我给后端传递的数组,对方接收不到。

1
2
3
4
5
6
7
8
$.ajax({
url: url,
type: type,
data: data, // eg: data.nicks = ['a', 'b', 'c']
success: function (data) {
//...
}
});

通过查资料,找到了解决办法:

1
2
3
4
5
@RequestMapping(value = "/update", method = RequestMethod.POST)
@ResponseBody
public Response<Integer> update(@RequestParam("_user") final String user, @RequestParam(value = "nicks[]") String[] nicks){
//...
}

接收参数需要这样写:@RequestParam(value = "nicks[]") String[] nicks,一定要是数组形式,才可以接收到。

But,问题出在上一周/(ㄒoㄒ)/~~ 因为node端用了request中转了一下,后端又接收不到了,同样的方法处理愣是不管用:

1
2
3
4
5
6
7
8
9
10
11
12
13
request(options, function (err, response, body) {
if (err) {
logger.error('api proxy error.', err);
res.send(rb.internalServerError());
return;
}
if (response.statusCode !== 200) {
logger.error("api proxy error. code: " + response.statusCode + ", body: " + body);
res.send(rb.internalServerError());
return;
}
res.send(body);
});

刚开始直接甩锅,这个问题不是遇到过嘛,肯定是后端没处理好。后来把我拉过去看看代码,好吧确实已经按照上次的经验处理了,然后开始找bug…
终于意识到request的不同之处,好吧开始看文档,发现:

form - when passed an object or a querystring, this sets body to a querystring representation of value,
and adds Content-type: application/x-www-form-urlencoded header. When passed no options,
a FormData instance is returned (and is piped to request). See “Forms” section above.

qsStringifyOptions - object containing options to pass to the qs.stringify method. Alternatively pass options to
the querystring.stringify method using this format {sep:';', eq:':', options:{}}. For example, to change the way
arrays are converted to query strings using the qs module pass the arrayFormat option with one of indices|brackets|repeat

继续查看qs

1
2
3
4
5
6
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' })
// 'a[0]=b&a[1]=c'
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' })
// 'a[]=b&a[]=c'
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' })
// 'a=b&a=c'

终于解决:在request触发发送之前,把数组参数处理一下,改成nicks[]=a&nicks[]=b&nicks[]=c这种格式就好啦,就是使用qs的方法:qs.stringify(object, [options]);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
options.qsStringifyOptions = {arrayFormat: 'brackets'};
request(options, function (err, response, body) {
if (err) {
logger.error('api proxy error.', err);
res.send(rb.internalServerError());
return;
}
if (response.statusCode !== 200) {
logger.error("api proxy error. code: " + response.statusCode + ", body: " + body);
res.send(rb.internalServerError());
return;
}
res.send(body);
});