这几天在处理移动端的新项目,新项目使用的是Vue2搭建的,ajax方面自然用了大名鼎鼎的axios来处理,但是使用过程中却出现了一些问题,导致后端接受不到前端传过去的数据。这里就此问题罗列一下自己的解决方案,以供参考。

先上代码(请求方式封装了一层):

const params = {
    phone: '13000000000',
    veriFyCode: '123456'
}
this.apiPost('/test', params).then((res) => {
    if (res.success) {
        console.log(true)
    } else {
        console.log(error)
    }
})
.catch((error) => {
    console.log(error)
})

写法跟jQuery的$.post差不多,写完之后跟后端联调,后端说他们无法接收到小呆发送过去的数据,但是这个接口是通用的,另一个同事之前开发的页面可以使用,所以后端童鞋认定此问题为前端导致。既然这?#27492;擔?#37027;咱就找找前端的原因吧,想了想这两个项目唯一不同的是老项目是用JQuery写的ajax,新项目是用axios写的ajax,想到这里,小呆打开Chrome开发者工具看了一下这两个ajax的发送信息发现了以下不同:

// axios下Request-Headers的Content-Type是
application/json;charset=UTF-8
// Request Payload为
{phone: "13000000000", veriFyCode: "123456"}

//jQuery下Request-Headers的Content-Type是
application/x-www-form-urlencoded;charset=UTF-8
// URL encode为
phone=13000000000&veriFyCode=123456

既然如此,小呆首先想到的办法就是,我们采用jQuery的方式去发送我们的数据,基于这个思维,小呆想到了2种方式解决:

首先不管用哪种方式,我们都需要通过设?#33804;?#23616;的默认配置,把axios的发送方式改一下:

//main.js
axios.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'

1. 使用URLSearchParams API:

改造封装的apiPost方法,通过URLSearchParams来组装我们的数据:

apiPost(url, data) {
    /* 处理参数为 key=value&key=value */
    let params = new URLSearchParams()
    for (var key in data) {
        params.append(key, data[key])
    }
    return new Promise((resolve, reject) => {
        this.$axios.post(url, params).then((response) => {
            resolve(response.data)
        }).catch((response) => {
            console.log('f', response)
        })
    })
}

需要注意的是:URLSearchParams不支持所有的浏览器,虽然是移动端的页面,但是为了避免个别机型的兼容问题,我们采用了另一种稳妥的方式处理:


2. 使用qs库来格式化数据

使用这种方式需要我们在项目中安装qs库作为格式化的?#35272;擔?/p>

npm install qs --save

main.js中,我们引入qs库并改造我们的apiPost方法:

// main.js
import qs from 'qs'
/* 注入vue全局中,这样我们可以在组件内或者JS内通过使用this.$qs来使用qs库*/
Vue.prototype.$qs = qs

//http.js
apiPost(url, data) {
    return new Promise((resolve, reject) => {
        this.$axios.post(url, this.$qs.stringify(data)).then((response) => {
            resolve(response.data)
        }).catch((response) => {
            console.log('f', response)
        })
    })
}

通过以上两种方法,问题就迎刃而解了,那么,这个问题难?#20048;?#33021;前端去修改吗?在之前公司做项目时,也是用axios发送的数据,且并未修改过什么东西,但是为什么现在后端接收不到我们的json类型的参数呢?

通过翻看axios的文档得知:在axios使用Post发送数据时,默认是直接把json放到请求体中提交到后端的,而后端获取数据的方?#25509;?#20004;种,一种是@RequestParam(通过字符串中解析出参数),另一种是@ResponseBody(从请求体中取参数),很显然,我们的后端用了第一种方式。

那么,既然知道了原因,兄弟们,懒得改前端代码的话,就怼回去吧( ‵▽′)ψ


总结

Q:axios Post无法传递数据的解决方案?
A1:使用URLSearchParams API
A2:使用qs库来格式化数据
A3:后端使用ResponseBody获取参数