axios傳遞參數傳不過去,post請求傳遞json參數,Vue實戰037:axios二次封裝和使用
什么是axios
Axios 是一個基于 promise 的 HTTP 庫,用(yong)于瀏覽(lan)器和(he)node.js等http客戶端,主要用(yong)來(lai)向(xiang)后臺發送各(ge)種業(ye)務請(qing)(qing)求(qiu)和(he)特殊處理(li),由于axios支(zhi)持后臺數據交(jiao)互(hu)、攔截請(qing)(qing)求(qiu)和(he)響應、取消請(qing)(qing)求(qiu)、超時設定(ding)、轉換json、防御(yu)XSRF攻擊(ji)等特性,Vue官方已(yi)經不再維護vue-resource并且推薦使用(yong)axios。
我們都知道在Vue中要頻繁的和(he)后臺進行數(shu)據交(jiao)互,所(suo)以(yi)對數(shu)據的處(chu)理是很(hen)關(guan)鍵的一步,不僅需要方便簡潔的請求操作,更需要確保數(shu)據安(an)全,所(suo)以(yi)axios當(dang)之(zhi)無愧的成為Vue的首選。
axios使用
安裝(zhuang)axios,進入項(xiang)目文件(jian)夾打開(kai)cmd,輸入,然后在main.js中全局(ju)引(yin)入axios,之(zhi)后在組件(jian)中調用(yong)(yong)即(ji)安裝(zhuang)axios,進入項(xiang)目文件(jian)夾打開(kai)cmd,輸入,然后在main.js中全局(ju)引(yin)入axios,之(zhi)后在每個用(yong)(yong)到的組件(jian)中調用(yong)(yong)。
#安裝axios npm install --save axios #main.js全局引入 import axios from 'axios' import qs from 'qs' Vue.prototype.$axios = axios Vue.prototype.$qs = qs #組件中使用 this.$axios.get(url,params).then(res=>{ console.log(res.data) }).catch(console.log(error))
為什么要二次封裝
1,代碼(ma)封裝,重用性高,減少(shao)代碼(ma)量,降低維護難度(du)。
2,統一處理一些常規(gui)的問(wen)題一勞永逸,如(ru)http錯誤。
3,攔(lan)截(jie)請求和響應,提前對數據進(jin)行(xing)處理(li),如獲(huo)取token,修改(gai)配(pei)置項(xiang)。
如何二次封裝
在src目錄中新建一個api文(wen)件夾,在里面新增(zeng)api.js和axios.js兩個文(wen)件,api.js用(yong)來(lai)統一管理api接(jie)口,而axios則用(yong)來(lai)二次封(feng)裝(zhuang)axios(以上是我個人的(de)方(fang)案(an),如果你(ni)覺得(de)更好的(de)方(fang)案(an)可(ke)以忽略(lve))。
引入組件
在axios.js中引入相應的(de)組(zu)件,qs模塊,用來序列化post類(lei)型的(de)數據(ju),element-ui提示(shi)框組(zu)件用來彈出提示(shi)信息,store用來獲(huo)取用戶(hu)的(de)token信息。
import axios from 'axios' // 引入axios import qs from 'axios'// 引入qs模塊,用來序列化post類型的數據 import {Message} from 'element-ui' //引入element-ui提示框框組件 import store from 'store' //引入store
設置請求超時、基本路由和post請求頭
通過axios.defaults.timeout可以設置默認的請求超時時間,當數據請求時間超過該設定時間時終止請求,這里我設置了5秒。之前我們在發送post的請求時發現,Vue默認的請求頭是
application/x-www-form-unlencoded,這種方式Django后臺無法接受到數據,所以我這直接給axios重新定義請求頭為Content-Type:
application/x-www-form-urlencoded。axios.defaults.baseURL可以用來(lai)設置(zhi)基本路由,方便統(tong)一設置(zhi)服務器域名(ming)。
axios.defaults.baseURL = '//127.0.0.1:8000/' //我是用djando搭建的后臺 axios.defaults.timeout = 5000; axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
請求攔截
顧名思義(yi),就(jiu)(jiu)是在(zai)發送(song)業務請(qing)求前進行(xing)阻(zu)攔,阻(zu)攔的(de)(de)目的(de)(de)是在(zai)數據發送(song)前對(dui)數據進行(xing)一(yi)定邏(luo)輯的(de)(de)處理,比如統一(yi)添加token,當然前提(ti)是我們在(zai)登錄的(de)(de)時候(hou)將(jiang)token通(tong)過(guo)localStorage或(huo)者cookie存在(zai)本地并更新至store中(zhong),然后每次發送(song)請(qing)求的(de)(de)時候(hou)就(jiu)(jiu)去store中(zhong)提(ti)取對(dui)應的(de)(de)token賦給header,后臺通(tong)過(guo)token來(lai)判斷(duan)用戶是否登錄。
// 請求攔截器(請求發出前處理一些請求) axios.interceptors.request.use( config => { // 每次發送請求之前判斷store中是否存在token,然后將token放入header,這樣就不用每次請求時都手動添加token了 const token = store.state.token; token && (config.headers.Authorization = token); return config; }, error => { return Promise.error(error); })
響應攔截
當axios拿到服務器返(fan)(fan)回給我們(men)的(de)(de)數(shu)據,對數(shu)據進行一(yi)些統(tong)一(yi)的(de)(de)處(chu)理,這里主要針對異(yi)常處(chu)理,如果(guo)后臺返(fan)(fan)回的(de)(de)狀態(tai)碼是200,則正常返(fan)(fan)回數(shu)據,如果(guo)請求(qiu)失敗(bai),那么我們(men)就(jiu)可以根據錯誤的(de)(de)狀態(tai)碼類型進行一(yi)些常規的(de)(de)異(yi)常處(chu)理方案。
// 響應攔截器(處理響應數據) axios.interceptors.response.use( response => { if (response.data.code === 200) { return Promise.resolve(response) } else { return Promise.reject(response) } }, error => { let status = error.response.data.code if (code) { switch (code) { case 401: // 跳轉登錄頁面并將要瀏覽的頁面fullPath傳過去 this.$router.replace({ path: '/login', query: { redirect: this.$router.currentRoute.fullPath } }) break case 500: //* ****省略*** */ break default: Message.error(error.response.data.message) break } return Promise.reject(error.response) } } )
封裝post、 get 、put 、delete方法
接(jie)下(xia)來我們可以(yi)來封裝(zhuang)一些常用(yong)的請求方(fang)法(fa),在(zai)項目中我們比較常用(yong)的方(fang)法(fa)有(you)post、 get 、put 、delete,接(jie)下(xia)來我們對這(zhe)幾(ji)個方(fang)法(fa)進(jin)行(xing)(xing)二次封裝(zhuang),將url和(he)header進(jin)行(xing)(xing)封裝(zhuang),這(zhe)樣(yang)在(zai)使用(yong)的時候我們只需(xu)要調用(yong)接(jie)口函數以(yi)及傳入params即可。這(zhe)里我統一返(fan)回了(le)res.data,所以(yi)在(zai)獲(huo)取數據(ju)的時候注意下(xia)層次,最好用(yong)console.log打(da)印(yin)下(xia)獲(huo)取的數據(ju),別(bie)拿錯(cuo)了(le)數據(ju)。
封裝get/delete方法
定(ding)義一個(ge)get/del函數,傳遞(di)有兩個(ge)參數,參數1url地址,參數2攜帶(dai)的(de)請(qing)(qing)求參數。然后返回(hui)一個(ge)promise對象,請(qing)(qing)求成(cheng)功時(shi)resolve服(fu)務器(qi)返回(hui) 值,請(qing)(qing)求失敗時(shi)reject錯(cuo)誤(wu)。
// 封裝get請求 function get (url, params) { return new Promise((resolve, reject) => { axios.get(url, { params: params }).then(res => { resolve(res.data) }).catch(err => { reject(err.data) }) }) } // 封裝delete請求 function del (url, params) { return new Promise((resolve, reject) => { axios.delete(url, { params: params }).then(res => { resolve(res.data) }).catch(err => { reject(err.data) }) }) }
封裝post/put方法
post需要注意的就是需要對參數進行序列化操作,否則后臺是拿不到你提交的數據,axios中提供了qs模塊,可以對參數進行序列化,在axios中引入this.$qs.stringify(),這樣在傳參前將數據自動處理成鍵值對形式,這里我們可以看到發送的數據格式為Form Data(請求頭 Content-Type:
application/x-www-form-urlencoded),后臺也(ye)正常接收到(dao)了(le)數據。
// 封裝post請求 function post (url, params) { return new Promise((resolve, reject) => { axios.post(url, qs.stringify(params)) .then(res => { resolve(res.data) }).catch(err => { reject(err.data) }) }) } // 封裝put請求 function put (url, params) { return new Promise((resolve, reject) => { axios.put(url, qs.stringify(params)) .then(response => { resolve(response.data) }).catch(err => { reject(err) }) }) }
拋出方法
最后我(wo)們(men)寫個導(dao)出函數,將方法拋出去,這(zhe)樣(yang)其他組件就(jiu)可以訪問到我(wo)們(men)封(feng)裝的方法了,通過(guo)提交的方法來判斷(duan)我(wo)們(men)該調(diao)用哪個方法。
// 拋出函數,對外的接口 export default function request (method, url, params) { if (method === 'get') { return get(url, params) } else if (method === 'delete') { return del(url, params) } else if (method === 'post') { return post(url, params) } else if (method === 'put') { return put(url, params) } }
全局注冊
全局(ju)引(yin)入(ru)axios.js文(wen)件(jian)(當然你也可(ke)以局(ju)部引(yin)用),這樣就不用在(zai)組(zu)件(jian)中(zhong)去調用了,因為我在(zai)axios中(zhong)只(zhi)有一個(ge)默認(ren)的函(han)數拋出(chu),所以我們不需要指定方法,直接調用該(gai)文(wen)件(jian)即可(ke)。
import request from '@/api/axios.js' Vue.prototype.$axios = request
組件中使用
現在我(wo)們就可(ke)(ke)以開心的使(shi)用封裝的axios了(le)(le),直接通過this.$axios()即(ji)可(ke)(ke)調用我(wo)們axios.js文(wen)件中的輸出函數,然后通過method來判斷(duan)調用哪個方法即(ji)可(ke)(ke)。因為前面我(wo)們已經定義(yi)了(le)(le)axios.defaults.baseURL,所以這里我(wo)們只(zhi)要附上路由(you)即(ji)可(ke)(ke),axios會自動為我(wo)們拼接路由(you)的。
this.$axios('post','login/',{ username:this.uname, password:this.password, }) .then(res=>{ console.log(res) if(res.data===200){ this.$store.commit('setToken',res.data.token) this.$Message({ message:'登錄成功', type:'success' }) this.$router.push('/home/info') } }) .catch(err => console.log(err))
歡迎關注本人的公眾號:編程手札,文章也會在(zai)公(gong)眾號(hao)更(geng)新