項目中對axios進行二次封裝
隨着前端技術的發展,網絡請求這一塊,越來越多的程序猿選擇使用axios來實現網絡請求。但是單純的axios插件並不能滿足我們日常的使用,因此我們使用時,需要根據項目實際的情況來對axios進行二次封裝。
接下來就我對axios的二次封裝詳細的說說,主要包括請求之前、返回響應以及使用等。
1、請求之前
一般的接口都會有鑒權認證(token)之類的,因此在接口的請求頭里面,我們需要帶上token值以通過服務器的鑒權認證。但是如果每次請求的時候再去添加,不僅會大大的加大工作量,而且很容易出錯。好在axios提供了攔截器機制,我們在請求的攔截器中可以添加token。
// 請求攔截
axios.interceptors.request.use((config) => {
//....省略代碼
config.headers.x_access_token = token
return config
}, function (error) {
return Promise.reject(error)
})
當然請求攔截器中,除了處理添加token以外,還可以進行一些其他的處理,具體的根據實際需求進行處理。
2、響應之后
請求接口,並不是每一次請求都會成功。那么當接口請求失敗的時候,我們又怎么處理呢?每次請求的時候處理?封裝axios統一處理?我想一個稍微追求代碼質量的碼農,應該都會選擇封裝axios進行統一處理吧。axios不僅提供了請求的攔截器,其也提供了響應的攔截器。在此處,可以獲取到服務器返回的狀態碼,然后根據狀態碼進行相對應的操作。
// 響應攔截
axios.interceptors.response.use(function (response) {
if (response.data.code === 401 ) {//用戶token失效
//清空用戶信息
sessionStorage.user = ''
sessionStorage.token = ''
window.location.href = '/';//返回登錄頁
return Promise.reject(msg)//接口Promise返回錯誤狀態,錯誤信息msg可有后端返回,也可以我們自己定義一個碼--信息的關系。
}
if(response.status!==200||response.data.code!==200){//接口請求失敗,具體根據實際情況判斷
message.error(msg);//提示錯誤信息
return Promise.reject(msg)//接口Promise返回錯誤狀態
}
return response
}, function (error) {
if (axios.isCancel(error)) {
requestList.length = 0
// store.dispatch('changeGlobalState', {loading: false})
throw new axios.Cancel('cancel request')
} else {
message.error('網絡請求失敗,請重試')
}
return Promise.reject(error)
})
當然響應攔截器同請求攔截器一樣,還可以進行一些其他的處理,具體的根據實際需求進行處理。
3、使用axios
axios使用的時候一般有三種方式:
- 執行get請求
axios.get('url',{
params:{},//接口參數
}).then(function(res){
console.log(res);//處理成功的函數 相當於success
}).catch(function(error){
console.log(error)//錯誤處理 相當於error
})
- 執行post請求
axios.post('url',{
data:xxx//參數
},{
headers:xxxx,//請求頭信息
}).then(function(res){
console.log(res);//處理成功的函數 相當於success
}).catch(function(error){
console.log(error)//錯誤處理 相當於error
})
- axios API 通過相關配置傳遞給axios完成請求
axios({
method:'delete',
url:'xxx',
cache:false,
params:{id:123},
headers:xxx,
})
//------------------------------------------//
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'monkey',
lastName: 'soft'
}
});
直接使用api的方式雖然簡單,但是不同請求參數的名字不一樣,在實際開發過程中很容易寫錯或者忽略,容易為開發造成不必要的時間損失。前面兩種方式雖然沒有參數不一致的問題,但是使用的時候,太過於麻煩。那么怎么辦呢?前面兩種雖然使用過於麻煩,但是仔細觀察,是可以發現有一定的相似點,我們便可以基於這些相似點二次封裝,形成適合我們使用的一個請求函數。直接上代碼:
/*
*url:請求的url
*params:請求的參數
*config:請求時的header信息
*method:請求方法
*/
const request = function ({ url, params, config, method }) {
// 如果是get請求 需要拼接參數
let str = ''
if (method === 'get' && params) {
Object.keys(params).forEach(item => {
str += `${item}=${params[item]}&`
})
}
return new Promise((resolve, reject) => {
axios[method](str ? (url + '?' + str.substring(0, str.length - 1)) : url, params, Object.assign({}, config)).then(response => {
resolve(response.data)
}, err => {
if (err.Cancel) {
} else {
reject(err)
}
}).catch(err => {
reject(err)
})
})
}
這樣我們需要接口請求的時候,直接調用該函數就好了。不管什么方式請求,傳參方式都一樣。