From 51c2c354ba84acd869823b1ba96cf617e7c5eb51 Mon Sep 17 00:00:00 2001 From: iczer <1126263215@qq.com> Date: Wed, 26 Aug 2020 13:17:56 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20add=20interceptors=20for=20axios;=20:bu?= =?UTF-8?q?g:=20=E6=96=B0=E5=A2=9E=EF=BC=9Aaxios=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=8B=A6=E6=88=AA=E5=99=A8=E9=85=8D=E7=BD=AE=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/bootstrap.js | 6 ++- src/main.js | 5 ++- src/utils/axios-interceptors.js | 71 +++++++++++++++++++++++++++++++++ src/utils/request.js | 40 ++++++++++++++++++- 4 files changed, 118 insertions(+), 4 deletions(-) create mode 100644 src/utils/axios-interceptors.js diff --git a/src/bootstrap.js b/src/bootstrap.js index b3f0226..6f779af 100644 --- a/src/bootstrap.js +++ b/src/bootstrap.js @@ -1,4 +1,6 @@ import {loadRoutes, loginGuard, authorityGuard} from '@/utils/routerUtil' +import {loadInterceptors} from '@/utils/request' +import interceptors from '@/utils/axios-interceptors' /** * 启动引导方法 @@ -7,7 +9,9 @@ import {loadRoutes, loginGuard, authorityGuard} from '@/utils/routerUtil' * @param store 应用的 vuex.store 实例 * @param i18n 应用的 vue-i18n 实例 */ -function bootstrap({router, store, i18n}) { +function bootstrap({router, store, i18n, message}) { + // 加载 axios 拦截器 + loadInterceptors(interceptors, {router, store, i18n, message}) // 加载路由 loadRoutes({router, store, i18n}) // 添加路由守卫 diff --git a/src/main.js b/src/main.js index f1e9538..21e5667 100644 --- a/src/main.js +++ b/src/main.js @@ -13,13 +13,14 @@ import bootstrap from '@/bootstrap' const router = initRouter(store.state.setting.asyncRoutes) const i18n = initI18n('CN', 'US') -bootstrap({router, store, i18n}) +Vue.use(Antd) Vue.config.productionTip = false Vue.use(Viser) -Vue.use(Antd) Vue.use(Plugins) +bootstrap({router, store, i18n, message: Vue.prototype.$message}) + new Vue({ router, store, diff --git a/src/utils/axios-interceptors.js b/src/utils/axios-interceptors.js new file mode 100644 index 0000000..53c3554 --- /dev/null +++ b/src/utils/axios-interceptors.js @@ -0,0 +1,71 @@ +import Cookie from 'js-cookie' +// 401拦截 +const resp401 = { + /** + * 响应数据之前做点什么 + * @param response 响应对象 + * @param options 应用配置 包含: {router, i18n, store, message} + * @returns {*} + */ + onFulfilled(response, options) { + const {message} = options + if (response.status === 401) { + message.error('无此接口权限') + } + return response + }, + /** + * 响应出错时执行 + * @param error 错误对象 + * @param options 应用配置 包含: {router, i18n, store, message} + * @returns {Promise} + */ + onRejected(error, options) { + const {message} = options + message.error(error.message) + return Promise.reject(error) + } +} + +const resp403 = { + onFulfilled(response, options) { + const {message} = options + if (response.status === 403) { + message.error(`请求被拒绝`) + } + return response + } +} + +const reqCommon = { + /** + * 发送请求之前做些什么 + * @param config axios config + * @param options 应用配置 包含: {router, i18n, store, message} + * @returns {*} + */ + onFulfilled(config, options) { + const {message} = options + const {url, xsrfCookieName} = config + if (url.indexOf('login') === -1 && xsrfCookieName && !Cookie.get(xsrfCookieName)) { + message.warning('认证 token 已过期,请重新登录') + } + return config + }, + /** + * 请求出错时做点什么 + * @param error 错误对象 + * @param options 应用配置 包含: {router, i18n, store, message} + * @returns {Promise} + */ + onRejected(error, options) { + const {message} = options + message.error(error.message) + return Promise.reject(error) + } +} + +export default { + request: [reqCommon], // 请求拦截 + response: [resp401, resp403] // 响应拦截 +} diff --git a/src/utils/request.js b/src/utils/request.js index 48af7ca..6d3f8c1 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -97,11 +97,49 @@ function checkAuthorization(authType = AUTH_TYPE.BEARER) { return false } +/** + * 加载 axios 拦截器 + * @param interceptors + * @param options + */ +function loadInterceptors(interceptors, options) { + const {request, response} = interceptors + // 加载请求拦截器 + request.forEach(item => { + let {onFulfilled, onRejected} = item + if (!onFulfilled || typeof onFulfilled !== 'function') { + onFulfilled = () => {} + } + if (!onRejected || typeof onRejected !== 'function') { + onRejected = () => {} + } + axios.interceptors.request.use( + config => onFulfilled(config, options), + error => onRejected(error, options) + ) + }) + // 加载响应拦截器 + response.forEach(item => { + let {onFulfilled, onRejected} = item + if (!onFulfilled || typeof onFulfilled !== 'function') { + onFulfilled = () => {} + } + if (!onRejected || typeof onRejected !== 'function') { + onRejected = () => {} + } + axios.interceptors.response.use( + response => onFulfilled(response, options), + error => onRejected(error, options) + ) + }) +} + export { METHOD, AUTH_TYPE, request, setAuthorization, removeAuthorization, - checkAuthorization + checkAuthorization, + loadInterceptors }