Commit 5e992c84 authored by lipengcheng 's avatar lipengcheng

feat: 新增axios拦截器及其他配置

parent 6cdefb37
......@@ -4,7 +4,7 @@ import router from './router'
import store from './store'
import './registerServiceWorker'
import './assets/style/index.scss'
import axios from '@/plugins/axios.js'
import requests from '@/plugins/axios.js'
import VueBus from 'vue-bus'
import VModal from 'vue-js-modal'
import moment from '@/plugins/moment.js'
......@@ -28,7 +28,8 @@ Vue.use(VueBus)
Vue.use(VModal)
Vue.config.productionTip = false
Vue.prototype.$http = axios
Vue.prototype.$request = requests.request
Vue.prototype.$axios = requests.pureAxios
Vue.prototype.$mt = moment
Vue.prototype.$ = utils
new Vue({
......
import axios from 'axios'
import handleStatus from '@/plugins/handleStatus.js'
import handleStatus from '@/plugins/axios.handleStatus.js'
// import store from '@/store/index'
// import router from '@/router/index.js'
// import { Message, Notification } from 'element-ui'
/**
* 默认配置
......@@ -15,7 +16,7 @@ axios.defaults.headers['b-laihua-defined-key'] = 'b customized value'
/**
* 请求拦截
*/
axios.interceptors.request.use(
const requestInterceptors = axios.interceptors.request.use(
(config) => {
// 在发送请求之前做些什么
// config.headers.common['cookie-id'] = cookieId
......@@ -29,7 +30,7 @@ axios.interceptors.request.use(
/**
* 响应拦截
*/
axios.interceptors.response.use(
const responseInterceptors = axios.interceptors.response.use(
(response) => {
return Promise.resolve(handleStatus(response))
},
......@@ -46,4 +47,17 @@ axios.interceptors.response.use(
}
)
// 移除请求拦截器
function removeRequestInterceptors() {
axios.interceptors.request.eject(requestInterceptors)
}
// 移除响应拦截器
function removeResponseInterceptors() {
axios.interceptors.response.eject(responseInterceptors)
}
axios.removeRequestInterceptors = removeRequestInterceptors
axios.removeResponseInterceptors = removeResponseInterceptors
export default axios
// 移除全局拦截器
// 如果设置了全局拦截器,想取消实例中发出的请求,必须先移除全局拦截器,实例中配置的config.cancelToken属性才会生效
import axios from 'axios'
import handleStatus from '@/plugins/handleStatus.js'
import handleStatus from '@/plugins/axios.handleStatus.js'
import setOptions from '@/plugins/axios.setOptions.js'
// import store from '@/store/index'
// import router from '@/router/index.js'
// import { Message, Notification } from 'element-ui'
/**
* 默认配置
*/
console.log('axios-process.env:', process.env)
axios.defaults.baseURL = process.env.VUE_APP_BASEURL
axios.defaults.timeout = 10000
axios.defaults.headers.common['a-laihua-defined-key'] = 'a customized value'
axios.defaults.headers['b-laihua-defined-key'] = 'b customized value'
// /**
// * 默认配置
// */
let pureAxios = setOptions(axios)
let request = setOptions(axios.create())
// 请求中的api
let pendingPool = new Map()
let conf = {}
/**
* 请求拦截
*/
axios.interceptors.request.use(
const requestInterceptors = request.interceptors.request.use(
(config) => {
request.config = Object.assign({}, config)
console.log('config:', config)
console.log('pendingPool:', pendingPool)
// 在发送请求之前做些什么
// config.headers.common['cookie-id'] = cookieId
config.cancelToken = new axios.CancelToken((cancelFn) => {
pendingPool.has(config.url) ? cancelFn(`${config.url}请求重复`) : pendingPool.set(config.url, { cancelFn, global: config.global })
})
return config
},
(err) => {
console.log('请求拦截err:', err)
// 对请求错误做些什么
Promise.reject(err)
}
......@@ -29,21 +45,63 @@ axios.interceptors.request.use(
/**
* 响应拦截
*/
axios.interceptors.response.use(
const responseInterceptors = request.interceptors.response.use(
(response) => {
const { config } = response
pendingPool.delete(config.url)
return Promise.resolve(handleStatus(response))
},
// 对响应错误做点什么
(err) => {
console.log('响应错误拦截err:', err)
console.log('响应拦截err:', err)
console.log('pendingPool2:', pendingPool)
console.log('axios.isCancel(err):', axios.isCancel(err))
// 错误信息err传入isCancel方法,可以判断请求是否被取消
if (axios.isCancel(err)) {
throw new axios.Cancel('cancel request')
throw new axios.Cancel(err.message || '请求被主动取消')
} else {
console.log('网络请求失败,请重试:')
pendingPool.delete(conf.url)
}
return Promise.reject(err)
}
)
export default axios
// 移除全局的请求拦截器
function removeRequestInterceptors() {
request.interceptors.request.eject(requestInterceptors)
}
// 移除全局的响应拦截器
function removeResponseInterceptors() {
request.interceptors.response.eject(responseInterceptors)
}
/**
* // 清除所有pending状态的请求
* @param {Array} whiteList 白名单,里面pending状态的请求不会被取消
* 返回值 被取消了的
*/
function clearPendingPool(whiteList = []) {
if (!pendingPool.size) return
const pendingUrlList = Array.from(pendingPool.keys()).filter((url) => !whiteList.includes(url))
if (!pendingUrlList.length) return
pendingUrlList.forEach((pendingUrl) => {
// 清除掉所有非全局的pending状态下的请求
if (!pendingPool.get(pendingUrl).global) {
pendingPool.get(pendingUrl).cancelFn()
pendingPool.delete(pendingUrl)
}
})
console.log('pendingUrlList:', pendingUrlList)
return pendingUrlList
}
request.removeRequestInterceptors = removeRequestInterceptors
request.removeResponseInterceptors = removeResponseInterceptors
request.clearPendingPool = clearPendingPool
export default {
pureAxios,
request
}
export default (axios, options = {}) => {
// /**
// * 默认配置
// */
// axios.defaults.baseURL = process.env.VUE_APP_BASEURL
// axios.defaults.timeout = 10000
// axios.defaults.headers.common['a-laihua-defined-key'] = 'a customized value'
// axios.defaults.headers['b-laihua-defined-key'] = 'b customized value'
const defaultOptions = {
baseURL: process.env.VUE_APP_BASEURL,
timeout: 10000,
headers: {
'Content-Type': 'application/json;charset=UTF-8',
'b-laihua-defined-key': 'b customized value',
common: {
'a-laihua-defined-key': 'a customized value'
}
}
}
Object.assign(axios.defaults, defaultOptions, options)
return axios
}
// 参考:https://juejin.im/post/6844904152833736712#heading-5
import Axios from 'axios'
import handleStatus from '@/plugins/handleStatus.js'
import handleStatus from '@/plugins/axios.handleStatus.js'
const baseURL = '/webapi' // 后台baseUrl
const axios = Axios.create({
......
// https://mp.weixin.qq.com/s/v7ku2KYAVW0r4Lmui4JNGA
import axios from 'axios'
import handleStatus from '@/plugins/handleStatus.js'
import handleStatus from '@/plugins/axios.handleStatus.js'
// import store from '@/store/index'
// import router from '@/router/index.js'
......
import Axios from 'axios'
import handleStatus from '@/plugins/handleStatus.js'
import handleStatus from '@/plugins/axios.handleStatus.js'
// import store from '@/store/index'
// import router from '@/router/index.js'
......
......@@ -6,7 +6,7 @@ import axios from 'axios'
let pendingRequest = []
/**
* 请求的拦截处理
* 请求的拦截处理d
* @param config - 请求的配置项
*/
const handleRequestIntercept = (config) => {
......@@ -26,7 +26,6 @@ const handleRequestIntercept = (config) => {
pendingRequest.splice(markIndex, 1)
}
// (重新)新建针对这次请求的axios的cancelToken标识
const CancelToken = axios.CancelToken
const source = axios.CancelToken.source()
config.cancelToken = source.token
// 设置自定义配置requestMark项,主要用于响应拦截中
......
// 通过Set数据结构阻止重复请求
// https://blog.csdn.net/Vue2018/article/details/105120206/
import axios from 'axios'
import handleStatus from '@/plugins/axios.handleStatus.js'
// import store from '@/store/index'
// import router from '@/router/index.js'
import { Message, Notification } from 'element-ui'
console.log('Message:', Message)
console.log('Notification:', Notification)
/**
* 默认配置
*/
console.log('axios-process.env:', process.env)
axios.defaults.baseURL = process.env.VUE_APP_BASEURL
axios.defaults.timeout = 10000
axios.defaults.headers.common['a-laihua-defined-key'] = 'a customized value'
axios.defaults.headers['b-laihua-defined-key'] = 'b customized value'
let pendingList = new Set()
console.log('pendingList:', pendingList)
/**
* 请求拦截
*/
axios.interceptors.request.use(
(config) => {
// 在发送请求之前做些什么
// config.headers.common['cookie-id'] = cookieId
config.cancelToken = new axios.CancelToken((c) => {
pendingList.has(config.url) ? c(`${config.url}请求重复`) : pendingList.add(config.url)
})
console.log('pendingList:', pendingList)
return config
},
(err) => {
console.log('err1:', err)
// 对请求错误做些什么
Promise.reject(err)
}
)
/**
* 响应拦截
*/
axios.interceptors.response.use(
(response) => {
const { config } = response
pendingList.delete(config.url)
return Promise.resolve(handleStatus(response))
},
// 对响应错误做点什么
(err) => {
console.log('响应错误拦截err:', err)
// 错误信息err传入isCancel方法,可以判断请求是否被取消
if (axios.isCancel(err)) {
throw new axios.Cancel('cancel request')
} else {
console.log('网络请求失败,请重试:')
}
return Promise.reject(err)
}
)
export default axios
// 移除全局拦截器
// 如果设置了全局拦截器,想取消实例中发出的请求,必须先移除全局拦截器,实例中配置的config.cancelToken属性才会生效
import axios from 'axios'
import handleStatus from '@/plugins/axios.handleStatus.js'
// import store from '@/store/index'
// import router from '@/router/index.js'
// import { Message, Notification } from 'element-ui'
/**
* 默认配置
*/
console.log('axios-process.env:', process.env)
axios.defaults.baseURL = process.env.VUE_APP_BASEURL
axios.defaults.timeout = 10000
axios.defaults.headers.common['a-laihua-defined-key'] = 'a customized value'
axios.defaults.headers['b-laihua-defined-key'] = 'b customized value'
// 请求中的api列表
let pendingList = new Set()
/**
* 请求拦截
*/
const requestInterceptors = axios.interceptors.request.use(
(config) => {
console.log('config:', config)
// 在发送请求之前做些什么
// config.headers.common['cookie-id'] = cookieId
config.cancelToken = new axios.CancelToken((c) => {
pendingList.has(config.url) ? c(`${config.url}请求重复`) : pendingList.add(config.url)
})
return config
},
(err) => {
console.log('err1:', err)
// 对请求错误做些什么
Promise.reject(err)
}
)
/**
* 响应拦截
*/
const responseInterceptors = axios.interceptors.response.use(
(response) => {
const { config } = response
pendingList.delete(config.url)
return Promise.resolve(handleStatus(response))
},
// 对响应错误做点什么
(err) => {
console.log('响应错误拦截err:', err)
// 错误信息err传入isCancel方法,可以判断请求是否被取消
if (axios.isCancel(err)) {
throw new axios.Cancel('cancel request')
} else {
console.log('网络请求失败,请重试:')
}
return Promise.reject(err)
}
)
// 移除全局的请求拦截器
function removeRequestInterceptors() {
axios.interceptors.request.eject(requestInterceptors)
}
// 移除全局的响应拦截器
function removeResponseInterceptors() {
axios.interceptors.response.eject(responseInterceptors)
}
axios.removeRequestInterceptors = removeRequestInterceptors
axios.removeResponseInterceptors = removeResponseInterceptors
export default axios
// 取消重复请求的基础上
// 新增移除所有pending状态请求的方法,并对外暴露,可用于路由切换时取消之前所有请求
import axios from 'axios'
import handleStatus from '@/plugins/axios.handleStatus.js'
// import store from '@/store/index'
// import router from '@/router/index.js'
// import { Message, Notification } from 'element-ui'
/**
* 默认配置
*/
console.log('axios-process.env:', process.env)
axios.defaults.baseURL = process.env.VUE_APP_BASEURL
axios.defaults.timeout = 10000
axios.defaults.headers.common['a-laihua-defined-key'] = 'a customized value'
axios.defaults.headers['b-laihua-defined-key'] = 'b customized value'
// 请求中的api
let pendingPool = new Map()
axios.config = {}
/**
* 请求拦截
*/
const requestInterceptors = axios.interceptors.request.use(
(config) => {
axios.config = Object.assign({}, config)
console.log('config:', config)
console.log('pendingPool:', pendingPool)
// 在发送请求之前做些什么
// config.headers.common['cookie-id'] = cookieId
config.cancelToken = new axios.CancelToken((cancelFn) => {
pendingPool.has(config.url) ? cancelFn(`${config.url}请求重复`) : pendingPool.set(config.url, { cancelFn, global: config.global })
console.log('pendingPool.has(config.url):', pendingPool.has(config.url))
})
return config
},
(err) => {
console.log('请求拦截err:', err)
// 对请求错误做些什么
Promise.reject(err)
}
)
/**
* 响应拦截
*/
const responseInterceptors = axios.interceptors.response.use(
(response) => {
const { config } = response
pendingPool.delete(config.url)
return Promise.resolve(handleStatus(response))
},
// 对响应错误做点什么
(err) => {
console.log('响应拦截err:', err)
console.log('pendingPool2:', pendingPool)
console.log('axios.isCancel(err):', axios.isCancel(err))
// 错误信息err传入isCancel方法,可以判断请求是否被取消
if (axios.isCancel(err)) {
throw new axios.Cancel(err.message || '请求被主动取消')
} else {
console.log('网络请求失败,请重试:')
pendingPool.delete(axios.config.url)
}
return Promise.reject(err)
}
)
// 移除全局的请求拦截器
function removeRequestInterceptors() {
axios.interceptors.request.eject(requestInterceptors)
}
// 移除全局的响应拦截器
function removeResponseInterceptors() {
axios.interceptors.response.eject(responseInterceptors)
}
// 清除所有pending状态的请求
function clearPendingPool() {
if (!pendingPool.size) return
const pendingUrlList = Array.from(pendingPool.keys())
pendingUrlList.forEach((pendingUrl) => {
console.log('pendingUrl:', pendingUrl)
// 清除掉所有非全局的pending状态下的请求
if (!pendingPool.get(pendingUrl).global) {
pendingPool.get(pendingUrl).cancelFn()
pendingPool.delete(pendingUrl)
}
})
}
axios.removeRequestInterceptors = removeRequestInterceptors
axios.removeResponseInterceptors = removeResponseInterceptors
axios.clearPendingPool = clearPendingPool
export default axios
import Vue from 'vue'
import VueRouter from 'vue-router'
import store from '@/store/index.js'
import requests from '@/plugins/axios.js'
Vue.use(VueRouter)
let routes = []
......@@ -56,6 +56,9 @@ const router = new VueRouter({
// 路由全局前置守卫
router.beforeEach((to, from, next) => {
// 路由变化时取消所有非全局的pending状态的请求
requests.request.clearPendingPool()
// 未登录情况下访问的页面需要登录,自动跳转到指定页面(登录页)
if (to.meta.needAuth && !store.getters['authed']) next({ name: 'page2' })
else next()
})
......
......@@ -24,14 +24,24 @@
<use xlink:href="#icon-14"></use>
</svg>
<div
style="width:50px;height: 20px;"
style="width:auto;height: 100px;border: 1px solid pink;margin-top:10px"
@click="aaa">
1111
发送请求 d
</div>
<div
style="width:50px;height: 20px;"
style="width:auto;height: 100px;border: 1px solid pink;margin-top:10px"
@click="bbb">
2222
取消请求
</div>
<div
style="width:auto;height: 100px;border: 1px solid pink;margin-top:10px"
@click="ccc">
实例中取消请求1
</div>
<div
style="width:auto;height: 100px;border: 1px solid pink;margin-top:10px"
@click="ccc1">
实例中取消请求2
</div>
</div>
</template>
......@@ -48,26 +58,57 @@ export default {
mounted() {},
methods: {
ttt() {
console.log('this.axios.CancelToken:', this.$http.CancelToken)
this.$store.dispatch('testAction')
},
async aaa() {
let CancelToken = this.$http.CancelToken
this.source = this.$http.CancelToken.source()
this.cancelObj = {}
let result = await this.$http.get('/home/banner?type=1&category=18', {
cancelToken: new CancelToken((c) => {
this.cancelObj.url = '///'
this.cancelObj.cancel = c
// this.$request.removeRequestInterceptors()
// let CancelToken = this.$request.CancelToken
// this.source = CancelToken.source()
let params = {
a: 1,
type: 1,
category: 18
}
let result = await this.$request
.get('/home/banner', {
params
// global: true
// cancelToken: this.source.token
})
.catch((err) => {
console.log('实例请求出错:', err, err.message)
})
})
console.log('this.cancelObj:', this.cancelObj)
console.log('result:', result)
},
bbb() {
console.log('this.source:', this.source)
async bbb() {
// this.source.cancel('333333333')
this.cancelObj.cancel()
// this.cancelObj.cancel()
this.$request.clearPendingPool()
// this.aaa()
},
async ccc() {
let source = this.$axios.CancelToken.source()
let result = this.$axios.get('/home/banner', {
cancelToken: source.token
})
console.log('result:', result)
setTimeout(() => {
source.cancel()
}, 500)
},
async ccc1() {
let cancelFn
this.$axios
.get('/home/banner', {
cancelToken: new this.$axios.CancelToken((c) => (cancelFn = c))
})
.then((data) => {
console.log('data:', data)
})
.catch((err) => console.log('err:', err))
setTimeout(() => {
cancelFn()
}, 500)
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment