axois包的安裝
npm install axios
一般在我們的項目中都有一個單獨的請求文件,在文件中我們引入axios包
import axios from 'axios'
// 設置請求超時時間
axios.defaults.timeout = 12000
// 設置請求的baseURL請求,(根據環境切換請求域名)
if (process.env.NODE_ENV == 'development') {
axios.defaults.baseURL = 'https://www.xx.com';}
else if (process.env.NODE_ENV == 'debug') {
axios.defaults.baseURL = 'https://www.ceshi.com';
}
else if (process.env.NODE_ENV == 'production') {
axios.defaults.baseURL = 'https://www.production.com';
}
// 設置post請求header頭部信息
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
攔截器
攔截器分爲請求攔截器和相應攔截器
請求攔截器:
axios.interceptors.request.use(
config => {
// 每次在發送請求的時候判斷header裏面是否有token,
// 如果存在,則統一在http請求的header都加上token,這樣後臺根據token判斷你的登錄情況
// 即使本地存在token,也有可能token是過期的,所以在響應攔截器中要對返回狀態進行判斷
let token = store.state.token;
token && (config.headers.token = token)
return token
},
// 請求報錯處理
error => {
return Promise.error(error)
}
)
相應攔截器
axios.interceptors.response.use(
response => {
// 如果返回的狀態碼爲200,說明接口請求成功,可以正常拿到數據
// 否則的話拋出錯誤
if (response.status === 200) {
return Promise.resolve(response);
} else {
return Promise.reject(response);
}
},
// 服務器狀態碼不是2開頭的的情況
// 這裏可以跟你們的後臺開發人員協商好統一的錯誤狀態碼
// 然後根據返回的狀態碼進行一些操作,例如登錄過期提示,錯誤提示等等
// 下面列舉幾個常見的操作,其他需求可自行擴展
error => {
if (error.response.status) {
switch (error.response.status) {
// 401: 未登錄
// 未登錄則跳轉登錄頁面,並攜帶當前頁面的路徑
// 在登錄成功後返回當前頁面,這一步需要在登錄頁操作。
case 401:
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
});
break;
// 403 token過期
// 登錄過期對用戶進行提示
// 清除本地token和清空vuex中token對象
// 跳轉登錄頁面
case 403:
Toast({
message: '登錄過期,請重新登錄',
duration: 1000,
forbidClick: true
});
// 清除token
localStorage.removeItem('token');
store.commit('loginSuccess', null);
// 跳轉登錄頁面,並將要瀏覽的頁面fullPath傳過去,登錄成功後跳轉需要訪問的頁面
setTimeout(() => {
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
});
}, 1000);
break;
// 404請求不存在
case 404:
Toast({
message: '網絡請求不存在',
duration: 1500,
forbidClick: true
});
break;
// 其他錯誤,直接拋出錯誤提示
default:
Toast({
message: error.response.data.message,
duration: 1500,
forbidClick: true
});
}
return Promise.reject(error.response);
}
}
});
Promise
- Promise是一個對象,可以保存狀態,異步執行代碼
new Promise(
function (resolve, reject) {
// 一段耗時的異步操作
resolve('成功') // 數據處理完成
// reject('失敗') // 數據處理出錯
}
).then(
(res) => {console.log(res)}, // 成功
(err) => {console.log(err)} // 失敗
)
封裝get請求
export function get(url, params){
return new Promise((resolve, reject) =>{
axios.get(url, {
params: params
}).then(res => {
resolve(res.data);
}).catch(err =>{
reject(err.data)
})
});}
post請求
export 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)
})
});
}
- 完整代碼如下所示
import axios from 'axios'
import qs from 'qs'
import {
Toast
} from 'vant'
// 設置請求公共參數,baseURL,請求頭,token
axios.default.timeout = 1000;
axios.default.baseURL = '';
// 設置post請求header頭部
axios.default.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
// 設置請求攔截器
axios.interceptors.request.use(
config => {
let token = store.getters['login/token'];
token && (config.headers.token = token)
return token
},
// 請求報錯處理
error => {
return Promise.error(error)
}
)
// 設置返回攔截器
axios.interceptors.response.use(
response => {
endLoading();
// 如果返回的狀態碼爲200,說明接口請求成功,可以正常拿到數據
// 否則的話拋出錯誤
if (response.status === 200) {
return Promise.resolve(response);
} else {
return Promise.reject(response);
}
},
// 服務器狀態碼不是2開頭的的情況
// 這裏可以跟你們的後臺開發人員協商好統一的錯誤狀態碼
// 然後根據返回的狀態碼進行一些操作,例如登錄過期提示,錯誤提示等等
// 下面列舉幾個常見的操作,其他需求可自行擴展
error => {
endLoading();
if (error.response.status) {
switch (error.response.status) {
// 401: 未登錄
// 未登錄則跳轉登錄頁面,並攜帶當前頁面的路徑
// 在登錄成功後返回當前頁面,這一步需要在登錄頁操作。
case 401:
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
});
break;
// 403 token過期
// 登錄過期對用戶進行提示
// 清除本地token和清空vuex中token對象
// 跳轉登錄頁面
case 403:
Toast({
message: '登錄過期,請重新登錄',
duration: 1000,
forbidClick: true
});
// 清除token
localStorage.removeItem('token');
store.commit('loginSuccess', null);
// 跳轉登錄頁面,並將要瀏覽的頁面fullPath傳過去,登錄成功後跳轉需要訪問的頁面
setTimeout(() => {
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
});
}, 1000);
break;
// 404請求不存在
case 404:
Toast({
message: '網絡請求不存在',
duration: 1500,
forbidClick: true
});
break;
// 其他錯誤,直接拋出錯誤提示
default:
Toast({
message: error.response.data.message,
duration: 1500,
forbidClick: true
});
}
return Promise.reject(error.response);
}
}
);
let loading = null;
// 封裝一個loding
function startLoading() {
loading = Toast.loading({
forbidClick: true,
className: "custom-toast",
loadingType: 'spinner',
message: '加載中...',
duration: 0
})
}
// 關閉loding
function endLoading() {
if(loading) loading.clear();
}
// 封裝一個get請求
export function get(url, params = {}){
// 開啓請求加載
startLoading();
return new Promise((resolve, reject) =>{
axios.get(url, {
params: params
})
.then(res => {
resolve(res.data);
})
.catch(err => {
reject(err.data)
})
})
}
// 封裝一個post請求
export function post(url, params) {
startLoading();
return new Promise((resolve, reject) => {
axios.post(url, QS.stringify(params))
.then(res => {
resolve(res.data);
})
.catch(err =>{
reject(err.data)
})
});
}