今天在用 vue axios 向后端传 post 请求时,请求参数死活传不过去,后来百度调研了一下,大致有以下两种解决方案:
- 第一种就是前端用常规方式发送,后端给参数加上@RequestBody注解,这种方式需要给每个请求参数都加上该注解,没必要代码能少则少,毕竟代码越少越精炼,无论在效率,稳定和可维护性上都会有提高。
this.$axios({
method: 'post',
url: '/user/insert',
data: {
username: 'aaa',
password: 'bbb'
}
})
- 另一种也是网上大部分的解决方案就是加上用 axios 自带的 qs 进行转换,但是这种方式不支持属性为对象集合的参数,容易形成类似于 user[0][username] 这样的参数,而实际我们需要的是 user[0].username
import qs from 'qs'
this.$axios({
method: 'post',
url: '',
data: qs.stringify({
username: 'aaa',
password: 'bbb',
students: [
{name: 'eeee'},
{name: 'cccc'},
]
}),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
- 所以介于上面两种情况我自己写了一个转换方法来解决这个问题供大家参考,咋们码界的一个理念就是避免重复造轮子,即使造了轮子也可以拿来和大家分享,一起来看看这个轮子漏不漏气
dataToForm(obj, formData, attrName) {
formData = formData ? formData : new FormData()
// 只有数组和对象才会递归
Object.keys(obj).forEach(key => {
const value = obj[key]
const type = typeof value
// 生成键名(键名如果是数组则追加 [index] 形式,否则 .xxx 形式)
const currAttrName = attrName ? attrName + (isNaN(key) ? '.' + key : '[' + key + ']') : key
// 如果值是基本类型直接追加
if(value == null || type == 'string' || type == 'number' || type == 'boolean' || value.constructor == File) {
formData.append(currAttrName, value)
}
// 如果只是对象类型递归处理
else if(type == 'object' && value) {
this.dataToForm(value, formData, currAttrName)
}
})
return formData
}
this.$axios({
method: 'post',
url: '',
data: this.dataToForm({
username: 'aaa',
password: 'bbb',
students: [
{name: 'eeee'},
{name: 'cccc'},
]
}),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})