關于Vue開發的問題(axios封裝)
在博客中查找vue的axios封裝,發現其中案例還是很多的,自己專案中有些需求不夠,
比如
1、Content-Type 請求頭 application/x-www-form-urlencoded和application/json兩種方式的應用
2、請求方式增加delete方式,
3、出現跨域,以及其他問題,
做了些修改,做個記錄
首先放出參考的源代碼
參考來源于 vue axios 封裝 全域呼叫axios
感謝 愛吃排骨 給予的幫助
import axios from "axios"
import qs from "qs"
axios.defaults.timeout=3000 //回應時間
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'; //配置請求頭
axios.defaults.baseURL =process.env.NODE_HOST; //配置介面地址
console.log(process.env)
//POST傳參序列化(添加請求攔截器)
axios.interceptors.request.use((config) => {
//在發送請求之前做某件事
let token = sessionStorage.getItem('access_token') || "" //獲取token
console.log(token)
if (token!="") {
config.headers = {
'access-token': token,
'Content-Type': 'application/x-www-form-urlencoded'
}
}
if(config.method === 'post'){
config.data = qs.stringify(config.data)//序列化post 引數
}
return config;
},(error) =>{
console.log('錯誤的傳參')
return Promise.reject(error);
});
//回傳狀態判斷(添加回應攔截器)
axios.interceptors.response.use((res) =>{
//對回應資料做些事
if(!res.data.success){
let newToken=res.data.token //成功后更新token
localStorage.setItem('access_token', newToken)
}
return res;
}, (error) => {
if(error.response.data.status=='401'){ //如果token 過期 則跳轉到登錄頁面
this.$router.push('/login');
}
return Promise.reject(error);
});
//回傳一個Promise(發送post請求)
function post(url, params) {
return new Promise((resolve, reject) => {
axios.post(url, params)
.then(response => {
resolve(response);
}, err => {
reject(err);
})
.catch((error) => {
reject(error)
})
})
}
//回傳一個Promise(發送get請求)
function get(url, param) {
return new Promise((resolve, reject) => {
axios.get(url, {params: param})
.then(response => {
resolve(response)
}, err => {
reject(err)
})
.catch((error) => {
reject(error)
})
})
}
export default {
get,
post,
}
直接粘貼過去使用的問題 — ,—!
1、第4行請求頭的的問題
2、第5行env檔案未說明如何應用
3、第14行,token 名稱的問題
4、第18行,當隨意使用qs進行轉序列化post引數 ,引數有時候想在body又有時候想在url的問題
5、新加delete,download下載方式
6、回應攔截器的修改
1、第4行請求頭的的問題
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
這里看到他是給axios添加默認的請求頭為:'application/x-www-form-urlencoded;'本身這樣寫是沒有錯誤的,但是只是默認了提交方式為表單提交,如果我們請求傳輸資料呢?就必須改為'application/json'?所以…為了能正常使用我又create另外一個axios2
let axios2 = axios.create()
axios2.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8'; //配置請求頭
問題來了,萬一get方式的請求頭也是這,咋辦,所以干脆寫在請求攔截器里
axios.interceptors.request.use((config) => {
//在發送請求之前做某件事 //請求之前加入token
let token = sessionStorage.getItem("token") || "" //獲取token
if (token != "") {
config.headers = {
'authorization': token, //寫自己后端傳回來的token的命名,本專案為 authorization,
'Content-Type': 'application/x-www-form-urlencoded'
}
}
if (config.method === 'post') {
config.data = qs.stringify(config.data)//序列化post 引數
}
return config;
}, (error) => {
console.log('錯誤的傳參')
return Promise.reject(error);
});
axios2.interceptors.request.use((config) => {
// //在發送請求之前做某件事 //請求之前加入token
let token = sessionStorage.getItem("token") || "" //獲取token
if (token != "") {
config.headers = {
'authorization': token, //寫自己后端傳回來的token的命名,本專案為 authorization,
'Content-Type': 'application/json;charset=UTF-8'
}
}
return config;
}, (error) => {
console.log('錯誤的傳參')
return Promise.reject(error);
});
對!只有
axios、axios2,以及'Content-Type'發生變化,是不是感覺繁瑣了很多,沒錯!但是勝在能用么,如果這個地方寫不對,請求會報400,引數錯誤,稍后我會放出完整版的,需要的直接拉到最下面吧
那么在下面封裝get,或者post 的時候,只需要使用兩個不同的axios就行,舉例:
//回傳一個Promise(發送post請求:'Content-Type'為form方式)
function post(url, params) {
return new Promise((resolve, reject) => {
axios.post(url, params)
.then(response => {
resolve(response);
}, err => {
reject(err);
})
.catch((error) => {
reject(error)
})
})
//回傳一個Promise(發送post請求:'Content-Type'為json方式)
function jsonpost(url, params) {
return new Promise((resolve, reject) => {
axios2.post(url, params)
.then(response => {
resolve(response);
}, err => {
reject(err);
})
.catch((error) => {
reject(error)
})
})
}
有點流水賬的意思,還是那句話,,,,,當時能用就行
2、第5行env檔案未說明如何應用
這個請參考我的其他博客《Vue開發問題——打包后首頁白屏》
3、第14行,token 名稱的問題
排骨老哥不地道(可能是我實在太菜),token名稱是后端定的,得隨時改,所以下面這個地方:
'access-token',得換成自己后端的token名稱,在1問題中,我封裝的攔截器,我的專案里名稱是叫authorization'
if (token!="") {
config.headers = {
'access-token': token,
'Content-Type': 'application/x-www-form-urlencoded'
}
}
4、第18行,當隨意使用qs進行轉序列化post引數 ,引數有時候想在body又有時候想在url的問題
細心的小伙伴可能發現了,我在封裝兩種請求攔截器的時候axios,比axios2多了億點點內容
if (config.method === 'post') {
config.data = qs.stringify(config.data)//序列化post 引數
}
所以如果在
'application/json'模式下,后端本來設定是在body中獲取資料,那么你再qs去轉換下,那么等你的就只有400
5、新加delete,download下載方式
直接上代碼
function deletefn(url, params) {
return new Promise((resolve, reject) => {
axios.delete(url+[params])
.then(response => {resolve(response)},err => {reject(err)})
.catch(err => {
reject(err)
})
});
}
function download(url, params) {
return new Promise((resolve, reject) => {
axios2.post(url, params, {responseType: 'blob'})
.then(response => {
resolve(response);
}, err => {
reject(err);
})
.catch((error) => {
reject(error)
})
})
}
這里注意了,洗掉的方式我是
axios.delete(url+[params]),你們看自己后臺的介面,可能會是axios.delete(url+'/'+[params]),這個 / 你們自己把握 [/滑稽]
至于下載請求嘛,是專案中一個匯出串列資訊的功能,具體請參考我的其他博客《vue開發問題——匯出文本流》
6、回應攔截器的修改
axios.interceptors.response.use((res) => {
// 對回應資料做些事
if (res.data&&res.data.code&&res.data.code == 401) {
console.log(this);
router.push('/');
}
return res;
});
作用是如果回傳碼401(無權限,或session過期)我就利用router去跳轉到登錄頁
原博主設定的是如果登錄的成功,就更新token,我這專案不需要,所以就偷個懶,有需要的可以自己試一試
這里有個小插曲,再這里參考router 必須是../比如:
import router from "../router"
最后記得自己封裝的方法要
export匯出哦~
下面是我完整的代碼,另外,還會附上axios封裝簡化版解決上述的
'Content-Type'問題
import axios from "axios"
import qs from "qs"
import router from "../router"
let axios2 = axios.create()
axios.defaults.timeout = 7000 //回應時間
axios2.defaults.timeout = 7000
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'; //配置請求頭
axios.defaults.baseURL = process.env.VUE_APP_BASE_API; //配置介面地址根目錄
axios2.defaults.baseURL = process.env.VUE_APP_BASE_API;
// //POST傳參序列化(添加請求攔截器)
axios.interceptors.request.use((config) => {
//在發送請求之前做某件事 //請求之前加入token
let token = sessionStorage.getItem("token") || "" //獲取token
if (token != "") {
config.headers = {
'authorization': token, //寫自己后端傳回來的token的命名,本專案為 authorization,
'Content-Type': 'application/x-www-form-urlencoded'
}
}
if (config.method === 'post') {
config.data = qs.stringify(config.data)//序列化post 引數
}
return config;
}, (error) => {
console.log('錯誤的傳參')
return Promise.reject(error);
});
// 回傳狀態判斷(添加回應攔截器)
axios.interceptors.response.use((res) => {
// //對回應資料做些事
if (res.data&&res.data.code&&res.data.code == 401) {
router.push('/');
}
return res;
});
axios2.interceptors.request.use((config) => {
// //在發送請求之前做某件事 //請求之前加入token
let token = sessionStorage.getItem("token") || "" //獲取token
if (token != "") {
config.headers = {
'authorization': token, //寫自己后端傳回來的token的命名,本專案為 authorization,
'Content-Type': 'application/json;charset=UTF-8'
}
}
return config;
}, (error) => {
console.log('錯誤的傳參')
return Promise.reject(error);
});
axios2.interceptors.response.use((res) => {
// 對回應資料做些事
if (res.data&&res.data.code&&res.data.code == 401) {
router.push('/');
}
return res;
});
//回傳一個Promise(發送請求頭為application/json的post請求)
function jsonpost(url, params) {
return new Promise((resolve, reject) => {
axios2.post(url, params)
.then(response => {
resolve(response);
}, err => {
reject(err);
})
.catch((error) => {
reject(error)
})
})
}
function jsonget(url, params) {
return new Promise((resolve, reject) => {
axios2.get(url, params)
.then(response => {
resolve(response);
}, err => {
reject(err);
})
.catch((error) => {
reject(error)
})
})
}
function jsondelete(url, params) {
return new Promise((resolve, reject) => {
axios2.delete(url, {data:params})
.then(response => {
resolve(response);
}, err => {
reject(err);
})
.catch((error) => {
reject(error)
})
})
}
//回傳一個Promise(發送post請求)
function post(url, params) {
return new Promise((resolve, reject) => {
axios.post(url, params)
.then(response => {
resolve(response);
}, err => {
reject(err);
})
.catch((error) => {
reject(error)
})
})
}
回傳一個Promise(發送get請求)
function get(url, param) {
return new Promise((resolve, reject) => {
axios.get(url, { params: param })
.then(response => { resolve(response) }, err => { reject(err) })
.catch((error) => { reject(error) })
})
}
function deletefn(url, params) {
return new Promise((resolve, reject) => {
axios.delete(url+[params])
.then(response => {resolve(response)},err => {reject(err)})
.catch(err => {
reject(err)
})
});
}
function download(url, params) {
return new Promise((resolve, reject) => {
axios2.post(url, params, {responseType: 'blob'})
.then(response => {
resolve(response);
}, err => {
reject(err);
})
.catch((error) => {
reject(error)
})
})
}
export default {
get,
post,
deletefn,
jsonpost,
jsonget,
jsondelete,
download
}
簡化版
function requset(config){
return new Promise((resolve,reject)=>{
axios({
url:config.url,
method:config.method,
headers:{
'authorization': config.token||'', //寫自己后端傳回來的token的命名,本專案為 authorization,
'Content-Type': 'application/json'||config.headers.Content-Type
},
params:config.params
}).then(res=>{
resolve(res)
}).catch(err=>{
reject(err)
})
})
}
其他地方呼叫
LoginInternet2(){
this.$ajax.requset({
url:"/login",
method:"post",
headers:{
"Content-Type":"application/x-www-form-urlencoded"
},
params:this.params
}).then(res =>{
console.log(res);
}).catch(err => {
console.log(err);
})
},
'authorization': config.token||'',表示如果傳入就是使用傳入的token,沒傳就不寫,其實這里還可以做個簡化的,直接添加攔截器就都解決了,
'Content-Type': 'application/json'||config.headers.Content-Type這個表示如果沒穿就是默認json,傳入就使用傳入的
下面的案例為了方便,引數我就直接寫再方法里了,一般是應該在data里面定義config:{…},去傳引數的,我懶嘛~
更新(其實是打錯了)————————————————————————————————
第1個問題里,上面寫的我為了創建axios2.去使用application/json請求頭 但是,axios少個2,后面的請求頭也打錯了 ,,囧,原文已經更改了
let axios2 = axios.create()
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'; //配置請求頭
幫到你的話,點個贊吧d=====( ̄▽ ̄*)b
轉載參考請注明https://blog.csdn.net/Lazy33/article/details/109400075 Lazy33
(引之我幸~讓我們大家創造良好環境,不隨便復制粘貼,畢竟程式員們人人皆紳士,是最可愛的! )
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/201510.html
標籤:其他
