這幾天在處理移動端的新項目,新項目使用的是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差不多,寫完之后跟后端聯調,后端說他們無法接收到小呆發送過去的數據,但是這個接口是通用的,另一個同事之前開發的頁面可以使用,所以后端童鞋認定此問題為前端導致。既然這么說,那咱就找找前端的原因吧,想了想這兩個項目唯一不同的是老項目是用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種方式解決:

首先不管用哪種方式,我們都需要通過設置全局的默認配置,把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庫作為格式化的依賴:

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)
        })
    })
}

通過以上兩種方法,問題就迎刃而解了,那么,這個問題難道只能前端去修改嗎?在之前公司做項目時,也是用axios發送的數據,且并未修改過什么東西,但是為什么現在后端接收不到我們的json類型的參數呢?

通過翻看axios的文檔得知:在axios使用Post發送數據時,默認是直接把json放到請求體中提交到后端的,而后端獲取數據的方式有兩種,一種是@RequestParam(通過字符串中解析出參數),另一種是@ResponseBody(從請求體中取參數),很顯然,我們的后端用了第一種方式。

那么,既然知道了原因,兄弟們,懶得改前端代碼的話,就懟回去吧( ‵▽′)ψ


總結

Q:axios Post無法傳遞數據的解決方案?
A1:使用URLSearchParams API
A2:使用qs庫來格式化數據
A3:后端使用ResponseBody獲取參數