前言:在做項目的時候正好同事碰到了這個問題,問為什么用axios在發送請求的時候沒有成功,請求不到數據,反而是報錯了,下圖就是報錯請求本尊
vue里代碼如下:
this.$http.post('/getMatterList.do',{"matterIds":"1,2,3"})
.then((res)=>{
console.log(res);
})
乍一看,沒毛病啊,請求不就是這么發的嗎,axios官方文檔都這么示范的呢,還能有錯?我們再來仔細看下瀏覽器里發出去的請求
有沒有發現什么蹊蹺,傳送參數的形式不是我們熟悉的form-data,而是Request Payload。莫慌,其實我們只要做兩步設置就可以解決了
- 用Qs.stringify()將對象序列化成URL的形式,Qs是axios里面自帶的,所以直接引入就可以了
- 設置請求頭里的'Content-Type'為'application/x-www-form-urlencoded'
import Qs from 'qs'
var data = Qs.stringify({"matterIds":"1,2,3"});
this.$http.post('/getMatterList.do',data, {headers:{'Content-Type':'application/x-www-form-urlencoded'}}).then((res)=>{
console.log(res)
})
改完之后再來看下,妥妥的了
問題是解決了,但是為什么呢?查閱一番資料之后,我又回來啦
HTTP請求中的get請求和post請求參數的存放位置是不一樣的,get請求的參數以鍵值對的方式跟在url后面的,而post請求的參數是以鍵值對的方式在請求體里的
- get請求
- post請求
為何要設置請求頭里的'Content-Type':
我們使用不同請求方式時,參數的傳輸方式是不一樣的,但是服務端在取我們接口的請求參數時,用的方法其實卻是一樣的,都是使用request.getParameter(key)來獲取,其實是因為tomcat在中間會對請求參數進行解析處理,處理完把解析出來的表單參數放在request parameter map中,所以后端就可以通過request.getParameter(key)來統一獲取數據,而tomcat解析的時候是怎么知道當前的請求是post請求的呢,就是通過'contentType',當'contentType'為"application/x-www-form-urlencoded",它才會去讀取請求體數據。
為何要用Qs.stringify()將對象序列化成URL的形式:
在最開始的時候我們說了,post請求參數是以鍵值對的形式存在請求體里,用Qs.stringify()就是把傳入的對象轉換為鍵值對。
最后在vue里用axios的時候,針對post請求的問題可以做一個全局的設置,避免每個請求都要設置一遍太麻煩