在項目中封裝axios的實戰(zhàn)過程
前言
在學(xué)習(xí)和做項目的時候經(jīng)常會碰到axios,之前做的項目一般都是配置好axios,所以自己一直有個大概印象,最近有個機會自己可以手動配置axios,順便記錄分享一下~
axios封裝的好處
axios封裝的好處是統(tǒng)一處理,提高效率,便于維護。
你可以像下面一樣這么使用axios請求接口
axios.get('http://localhost:10086/user?ID=12345')
.then(response => {
//成功后的操作...
})
.catch(error => {
//失敗后的操作...
});
但是當接口請求多起來,需求多起來的時候,在項目中每個需要接口請求的地方寫一遍這樣的代碼,這樣就會產(chǎn)生很多重復(fù)性的代碼,降低我們的開發(fā)效率和提高維護成本。
封裝思路
我們需要一次性集中配置axios,讓配置適應(yīng)我們項目的大部分場景。我們可以新建一個js文件,使用自定義配置新建一個 axios 實例,然后對實例進行基本配置,在請求前(請求體處理),請求后(返回的結(jié)果處理)等這些階段添加一些我們需要的處理,然后將其導(dǎo)出使用。
配置的優(yōu)先順序
配置會以一個優(yōu)先順序進行合并。這個順序是:在 lib/defaults.js 找到的庫的默認值,然后是實例的 defaults 屬性,最后是請求的 config 參數(shù)。(這樣有些特殊的場景我們也可以單獨處理)
node_modules文件夾下axios庫文件下的lib/defaults.js。

自定義實例默認值
const instance = axios.create({
baseURL: 'https://api.example.com'
});
請求的config參數(shù)
axios({
method:'get',
url:'http://bit.ly/2mTM3nY',
responseType:'stream' }).then(function(response) { response.data.pipe(fs.createWriteStream('ada_lovelace.jpg')) });
axios實例配置
1、定義一些常規(guī)的配置
設(shè)置BaseUrl
baseUrl一般有分為生產(chǎn)、開發(fā)、測試等多個地址,我們可以弄一個config.js進行存放,如果是vue或react我們可以新建env等文件進行存放,下面的baseUrl是使用react的環(huán)境變量的。
- 設(shè)置timeout請求超時的時間
- 設(shè)置數(shù)據(jù)請求的格式Content-Type(有 application/x-www-form-urlencoded、multipart/form-data、application/json...)等等
import axios from 'axios'
export const request = createAxiosInstance()
function createAxiosInstance () {
const instance = axios.create({
baseURL: process.env.REACT_APP_BASE_URL,
timeout: 5000,
headers: {
// 可定義統(tǒng)一的請求頭部
post: {
'Content-Type': 'application/json'
}
...
}
})
return instance
}
2、請求前加一些我們需要的操作,
比如需要在請求頭里添加token
請求參數(shù)判空處理
(下圖的例子傳了空的name和personId,這種會引起歧義,究竟是要獲取參數(shù)值為空還是忽略這些參數(shù)呢,有一些后端會進行一些處理,但前端還是盡量避免~)

每次接口請求時開啟loading動畫效果等等
// 添加請求攔截器(在發(fā)送請求之前做些什么)
instance.interceptors.request.use((config) => {
//可添加開啟loading效果的函數(shù)
loading.open()
//token 存在就添加到請求頭里
token && (config.headers.Authorization = token)
// 過濾請求參數(shù)中的 null undefined ''的函數(shù)
cleanObject()
return config
})
3、請求返回后,添加攔截操作,
- 處理成功返回的數(shù)據(jù)
比如后端返回的data數(shù)據(jù)可能嵌套了很多層,你可以直接返回你需要的data數(shù)據(jù),這樣業(yè)務(wù)代碼就可以直接拿到最終的數(shù)據(jù),而不用每次去解構(gòu)之類的。
- 統(tǒng)一處理失敗后的異常報錯
接口請求有成功也有失敗,如果你不想在每寫一個接口請求的時候都需要去寫一遍失敗的邏輯代碼,并且?guī)缀醵际侵貜?fù)的時候,那你可以在這里集中進行接口的統(tǒng)一的異常處理。如判斷狀態(tài)碼或后端自定義的code,并把后端返回的錯誤提示顯示出來。
// 添加響應(yīng)攔截器(對響應(yīng)數(shù)據(jù)做點什么)
instance.interceptors.response.use((response) => {
//可添加關(guān)閉loading效果的函數(shù)
loading.close()
//解構(gòu)出返回結(jié)果的數(shù)據(jù)
const res = response.data
//對自定義code碼進行判斷,將成功的數(shù)據(jù)返回出去
const validateStatus = /^(2|3)\d{2}$/ //code為2或3開頭的視作請求成功
if (validateStatus.test(res.code)) {
return res //直接return出去我們需要的data
}
//判斷失敗的code碼并作出提示等操作
if (res.code === 401) {
message.error(res.msg)
} else {
message.warning(res.msg)
}
return Promise.reject(res)
},
(error) => {
loading.close()
if (error.response.status === 401) {
message.error('token失效,請重新登錄!')
removeStorageToken()
setTimeout(() => {
window.location.href = '/login'
}, 2000)
} else {
if (!window.navigator.onLine) {
message.warning('網(wǎng)絡(luò)異常,請檢查網(wǎng)絡(luò)是否正常連接')
} else if (error.code === 'ECONNABORTED') {
message.warning('請求超時')
} else {
message.warning('服務(wù)器異常,請聯(lián)系管理員')
}
}
return Promise.reject(error) // 將錯誤繼續(xù)返回給到具體頁面
}
)
上面有根據(jù)HTTP狀態(tài)碼和自定義code做的一些錯誤處理,這里進行了錯誤攔截后,頁面進行業(yè)務(wù)接口調(diào)用的時候就不用再每次進行錯誤提示處理。當然要根據(jù)不同項目需求進行配置。
請求接口方法統(tǒng)一管理
一般我們會把所有的接口請求方法寫在一起進行統(tǒng)一管理,后期更改的時候也方便查找維護。

我們可以新建一個管理api請求的文件夾(如apiList),里面放我們各種請求文件(這里按功能分)。如user.js就存放用戶相關(guān)的請求,其他類推。然后頁面就可以直接引用方法進行接口調(diào)用。
import { request } from '../axios'
// 獲取用戶信息
export function getUserInfo (userId) {
return request.get(`/sys/user/info/${userId}`)
}
在組件或頁面直接調(diào)用方法就可以了~
最后放一下完整的示例!大家可以參考一下~
這個示例配置適用于vue或react,當然每個項目的配置都會有些不同,小伙伴要根據(jù)自己項目進行修改配置和擴充~
import axios from 'axios'
export const request = createAxiosInstance()
function createAxiosInstance () {
const instance = axios.create({
baseURL: process.env.REACT_APP_BASE_URL,
timeout: 5000,
headers: {
// 可定義統(tǒng)一的請求頭部
post: {
'Content-Type': 'application/json'
}
...
}
})
// 添加請求攔截器(在發(fā)送請求之前做些什么)
instance.interceptors.request.use((config) => {
//可添加開啟loading效果的函數(shù)
loading.open()
//token 存在就添加到請求頭里
token && (config.headers.Authorization = token)
// 過濾請求參數(shù)中的 null undefined ''的函數(shù)
cleanObject()
return config
})
// 添加響應(yīng)攔截器(對響應(yīng)數(shù)據(jù)做點什么)
instance.interceptors.response.use((response) => {
//可添加關(guān)閉loading效果的函數(shù)
loading.close()
//解構(gòu)出返回結(jié)果的數(shù)據(jù)
const res = response.data
//對自定義code碼進行判斷,將成功的數(shù)據(jù)返回出去
const validateStatus = /^(2|3)\d{2}$/ //code為2或3開頭的視作請求成功
if (validateStatus.test(res.code)) {
return res
}
//判斷失敗的code碼并作出提示等操作
if (res.code === 401) {
message.error(res.msg)
} else {
message.warning(res.msg)
}
return Promise.reject(res)
},
(error) => {
loading.close() //可添加關(guān)閉loading效果的函數(shù)
if (error.response.status === 401) {
message.error('token失效,請重新登錄!')
removeStorageToken()
setTimeout(() => {
window.location.href = '/login'
}, 2000)
} else {
if (!window.navigator.onLine) {
message.warning('網(wǎng)絡(luò)異常,請檢查網(wǎng)絡(luò)是否正常連接')
} else if (error.code === 'ECONNABORTED') {
message.warning('請求超時')
} else {
message.warning('服務(wù)器異常,請聯(lián)系管理員')
}
}
return Promise.reject(error) // 將錯誤繼續(xù)返回給到具體頁面
}
)
return instance
}
總結(jié)
到此這篇關(guān)于在項目中封裝axios的文章就介紹到這了,更多相關(guān)項目中封裝axios內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue.js結(jié)合Ueditor富文本編輯器的實例代碼
本篇文章主要介紹了Vue.js結(jié)合Ueditor的項目實例代碼,這里整理了詳細的代碼,具有一定的參考價值,有興趣的可以了解一下2017-07-07
vue-treeselect(適配Vue3.2)及Element-plus的TreeSelect組件使用
這篇文章主要介紹了vue-treeselect(適配Vue3.2)及Element-plus的TreeSelect組件使用,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05
vue中使用mixins/extends傳入?yún)?shù)的方式
這篇文章主要介紹了vue中使用mixins/extends傳入?yún)?shù)的方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-05-05
vue.js調(diào)用python腳本并給腳本傳數(shù)據(jù)
在有些情況下需要使用不同的語言來完成一個項目,因此就有可能出現(xiàn)不同語言的程序之間的相互調(diào)用,下面這篇文章主要給大家介紹了關(guān)于vue.js調(diào)用python腳本并給腳本傳數(shù)據(jù)的相關(guān)資料,需要的朋友可以參考下2024-03-03
vue3+element?Plus實現(xiàn)表格前端分頁完整示例
這篇文章主要給大家介紹了關(guān)于vue3+element?Plus實現(xiàn)表格前端分頁的相關(guān)資料,雖然很多時候后端會把分頁,搜索,排序都做好,但是有些返回數(shù)據(jù)并不多的頁面,或者其他原因不能后端分頁的通常會前端處理,需要的朋友可以參考下2023-08-08
vue-cli構(gòu)建的項目如何手動添加eslint配置
這篇文章主要介紹了vue-cli構(gòu)建的項目如何手動添加eslint配置,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-04-04

