后台写了个接口,有一个数组类型的参数。

    @DeleteMapping("")
    public void get(Set<String> ids) {
        ...
    }

想着通过 axios.js 进行调用,刚开始写出如下代码:

const axios = require('axios');

axios.get(`http://localhost:8080/get`, {
    params: {
      "ids": ["a1","a2"]
    }
  })
  .then(function (resp) {
    console.log(resp);
  });

gg,调不通后台接口。上面的写法实际请求的 url/get?ids[]=a1&ids[]=a2
可以看出来,数组参数 ids 默认加上了[],这样导致后台无法正确解析获取该参数值。
预期的 url/get?ids=a1&ids=a2 ,那么如何将[]去掉呢?

实际上,axios.js的官方文档有说明这一点,参看:http://www.axios-js.com/zh-cn/docs/#请求配置。其中 paramsSerializer 配置项正是params序列化的关键。如下:
(简单解释下序列化的作用:params参数会拼接到url上,所以一定要是一个字符串形式的值。所以序列化的作用就是将array或者object类型的对象转换成字符串类型。)

//其他配置忽略...
   // `paramsSerializer` 是一个负责 `params` 序列化的函数
  paramsSerializer: function(params) {
    return Qs.stringify(params, {arrayFormat: 'brackets'})
  },
//其他配置忽略...

从上面的代码可以得知,axios.js 使用 qs工具库 来实现序列化。默认序列化方式为:Qs.stringify(params, {arrayFormat: 'brackets'})

查阅 qs库的文档,结合我们的问题,对于数组类型的序列化规则关键的配置是 arrayFormat ,该配置有四种策略。参看:https://www.npmjs.com/package/qs#parsing-arrays
该配置的四种策略以及相应的序列化效果如下:

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'
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'comma' })
// 'a=b,c'

我们预期的url格式是 /get?ids=a1&ids=a2,可见 ‘repeat’ 策略才是我们想要的。

所以调整一下 axios 调用代码,覆盖默认的序列化配置即可:

const axios = require('axios');
const qs = require('qs');

axios.get(`http://localhost:8080/get`, {
    params: {
      "ids": ["a1", "a2"]
    },
    paramsSerializer: function (params) {
      return qs.stringify(params, { arrayFormat: 'repeat' })
    }
  })
  .then(function (resp) {
    console.log(resp);
  });

这下好了,url为 /get?ids=a1&ids=a2。搞定。

你以为这就玩完了??!
按上面的操作,每一个调用代码都要写这段配置,也太麻烦了吧。
哈哈,强大的 axios.js 当然提供了修改全局默认配置的方式。通过 axios.defaults 即可。参见:http://www.axios-js.com/zh-cn/docs/#全局的 axios 默认值
最终的代码如下:

const axios = require('axios');
const qs = require('qs');

// axios 全局配置
axios.defaults.paramsSerializer = function(params) {
  return qs.stringify(params, {arrayFormat: 'repeat', allowDots: true})
};

axios.get(`http://localhost:8080/get`, {
    params: {
      "ids": ["a1", "a2"]
    }
  })
  .then(function (resp) {
    console.log(resp);
  });

搞定!


end

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐