注意點(diǎn):不要直接對(duì)axios原型設(shè)置攔截,先創(chuàng)建axios實(shí)例: axios.create
然后分別用到:
service.interceptors.request.use
service.interceptors.response.use
攔截器代碼:
import axios from 'axios';
import router from '../router';
import db from '@/utils/localstorage';
import { MessageBox, Message, Loading } from 'element-ui';
import store from '@/store';
import { getToken } from '@/utils/auth';
var aaa = 0
let nowUrl = '';
// 創(chuàng)建axios實(shí)例
const service = axios.create({
// baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
// withCredentials: true, // 跨域請(qǐng)求時(shí)發(fā)送cookie
baseURL: config.BASE_API,
timeout: 30000 // 請(qǐng)求超時(shí)
});
// 請(qǐng)求攔截器
let loadingInstance = null;
service.interceptors.request.use(
(config) => {
nowUrl = config.url;
// do something before request is sent
var xtoken = localStorage.getItem('loginToken');
config.headers['tenantPath'] = (window.location.pathname.split('/')[1] === 'sdm' ? window.location.pathname.split('/')[2] : window.location.pathname.split('/')[1]) || '';
config.headers['t'] = store.getters.t;
if (xtoken != null) {
config.headers['X-User'] = getToken();
config.headers['System'] = 'M';
config.headers['crmversion'] = 'V1.0.0';
config.headers['channel'] = 'PC';
config.headers['Content-Type'] = 'application/json';
}
if (config.responseType === 'blob') { // blob類(lèi)型 延長(zhǎng)超時(shí)時(shí)間
config.timeout = 60000;
loadingInstance = Loading.service({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
}
if (config.url.includes('add') || config.url.includes('edit') || config.url.includes('update') || config.url.includes('create')) {
loadingInstance = Loading.service({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
}
if (config.url.indexOf('entrust/query/pagination')) {
config.timeout = 300000;
}
if (config.url.includes('/member/import') || config.url.includes('/dataSetRoler/import')) { // 導(dǎo)入文件設(shè)置請(qǐng)求頭
config.headers['Content-Type'] = 'multipart/form-data';
}
return config;
},
(error) => {
// 處理請(qǐng)求錯(cuò)誤
console.log(error); // for debug
return Promise.reject(error);
}
);
// 響應(yīng)攔截器
service.interceptors.response.use(
/**
* 如果您想獲得http信息月腋,例如頭信息或狀態(tài)信息
* 請(qǐng)返回 response => response
*/
/**
* 通過(guò)自定義代碼確定請(qǐng)求狀態(tài)
* 這里只是一個(gè)例子
* 還可以通過(guò)HTTP狀態(tài)代碼來(lái)判斷狀態(tài)
*/
(response) => {
if (response.config.responseType === 'blob') { // 下載時(shí)直接return 返回blob
loadingInstance && loadingInstance.close();
return response.data;
}
if (response.config.url.includes('add') || response.config.url.includes('edit') || response.config.url.includes('update') || response.config.url.includes('create')) {
loadingInstance && loadingInstance.close();
}
const res = response.data;
// 如果狀態(tài)碼不是0缀辩,則判斷為錯(cuò)誤。
if (res.status !== 0 && res.status !== 200) {
if (res.status == '400') {
Message.closeAll(); // 關(guān)閉之前的彈出信息
Message({
dangerouslyUseHTMLString: true,
message: res.message || 'Error',
type: 'error',
duration: 5 * 1000
});
}
// 50008: 非法的令牌; 50012: 其他客戶(hù)端登錄; 50014: 令牌過(guò)期;
if (res.code === 401 || res.code === 50012 || res.code === 50014) {
// 重新登陸
MessageBox.confirm('很抱歉,登錄已過(guò)期,請(qǐng)重新登錄', {
confirmButtonText: '重新登錄',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
store.dispatch('user/resetToken').then(() => {
location.reload();
});
});
}
return Promise.reject(res);
} else {
return res;
}
},
(error) => {
console.log('err' + error.request.response); // for debug
if (!error.request.response) {
Message({
message: '服務(wù)連接失敗',
type: 'error',
duration: 5 * 1000
});
return Promise.reject(error);
}
const err = JSON.parse(error.request.response);
loadingInstance && loadingInstance.close();
if (nowUrl.indexOf('/menu/getList') != '-1') {
return Promise.reject(error);
}
if (error.request &&
error.request.response &&
JSON.parse(error.request.response) &&
JSON.parse(error.request.response).status === 600 &&
JSON.parse(error.request.response).message) {
return Promise.reject(error);
}
if (err.status === 401 && nowUrl.indexOf('/menu/getList') == '-1') {
// 重新登陸
if (aaa == 0) {
aaa++
MessageBox.confirm('很抱歉,登錄已過(guò)期锹漱,請(qǐng)重新登錄', {
confirmButtonText: '重新登錄',
showCancelButton: false,
type: 'warning'
}).then(() => {
db.remove('router')
db.remove('loginToken')
aaa = 0
router.push({ path: '/login' });
});
}
return Promise.reject(error);
}
if (
error.request &&
error.request.response &&
JSON.parse(error.request.response) &&
JSON.parse(error.request.response).status == 400 &&
JSON.parse(error.request.response).message
) {
Message({
message: JSON.parse(error.request.response).message,
type: 'error',
duration: 5 * 1000
});
return Promise.reject(error);
}
if (error.message.indexOf('timeout') !== -1) {
Message({
message: '請(qǐng)檢查網(wǎng)絡(luò)后重試',
type: 'error',
duration: 5 * 1000
});
return Promise.reject(error);
} else {
Message({
message: JSON.parse(error.request.response).message,
type: 'error',
duration: 5 * 1000
});
return Promise.reject(error);
}
}
);
export default service;
上面我們對(duì)響應(yīng)狀態(tài) 401 500 其他等狀態(tài)的錯(cuò)誤處理封裝的很詳細(xì),以及code異常時(shí)的提示都做了處理类溢;
在調(diào)用時(shí)不需要再處理 異常status 或者異常code 的情況凌蔬,小心頁(yè)面上發(fā)生兩次錯(cuò)誤提示哈露懒!
注意上面是 export default service; 有default, 所以我們?cè)赼pi文件里引用時(shí) import request from '@/utils/request' ,這里的request可以是任何自定義的名稱(chēng)~
調(diào)用接口代碼:manage.js
import request from '@/utils/request'
const prefix = 'web'
export function getKey() {
return request({
url: prefix + '/member/ldap/getKey',
method: 'get'
});
}
export function getValidCode(data) {
return request({
url: prefix + '/captcha',
method: 'get',
data
});
}
封裝到上面的程度后砂心,每次調(diào)用接口時(shí)需要 把manage.js 里的方法一個(gè)個(gè)import進(jìn)來(lái)懈词,非常不方便
可以看我下篇筆記,只需要一步一次輸出manage.js文件所有方法辩诞,在調(diào)用時(shí)就不需要逐個(gè)引入啦