Commit c60b82cf authored by lipengcheng 's avatar lipengcheng

fix: 一些axios相关优化

parent 0482d4ae
/**api管理页面
* apiMap中新增需要的api
* 导出的requestMap是一个对象,属性名为调用时的名称,值为实际请求方法
* 方法接收两个对象参数,第一个为需要传递的数据,第二个为请求的配置
* apiMap: 统一管理所有api地址、对应的请求方式及自定义别名
* 导出一个对象requestMap,属性名为apiMap中定义的别名,也就是调用时的名称,值为实际请求方法
* 方法接收两个对象参数,第一个为需要传递的数据,第二个为请求头的配置信息。
* 语法: api[alias](paramsOrData, headersConfig)
* 第一个参数:如果为put/post/patch方法中的一种,会被转化为data属性;其余则是params
* 第二个参数:请求配置
* 第二个参数:请求头信息
*
* let xx = await this.$api.getBanner({ account: '18038018084', psw: '2' })
* let vv = await this.$api.login({ account: '18038018084', psw: '2' })
*
* 如果类似post的方法需要通过url后缀形式传递参数,在第二个参数config加上params属性即可:
* let vv = await this.$api.login({ account: '18038018084', psw: '2' },{ params: {} })
* 设置请求信息及请求头:
*
* 自定义请求头信息:
* let xx = await this.$api.getBanner({}, {timeout: 1000, headers:{ aaa: 111 }})
*/
import { request } from '@/plugins/axios/index'
......
......@@ -29,7 +29,7 @@ Vue.use(VModal)
Vue.config.productionTip = false
Vue.prototype.$request = requests.request
Vue.prototype.$pureRequest = requests.pureRequest
Vue.prototype.$intactRequest = requests.intactRequest
Vue.prototype.$api = api
Vue.prototype.$mt = moment
Vue.prototype.$ = utils
......
export default (axios, config = {}) => {
// /**
// * 默认配置
// */
// 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'
// axios.defaults.headers['custom-defined-header-key'] = 'custom-defined-header-value'
// // 自定义请求头:对所有请求方法生效
// axios.defaults.headers.common['common-defined-key-b'] = 'custom value: for all methods'
// // 自定义请求头:只对post方法生效
// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
// // 自定义请求头:只对get方法生效
// axios.defaults.headers.get['get-custom-key'] = 'custom value: only for get method';
const defaultConfig = {
baseURL: process.env.VUE_APP_BASEURL,
timeout: 10000,
headers: {
'Content-Type': 'application/json;charset=UTF-8',
'b-laihua-defined-key': 'b customized value',
'custom-defined-header-key': 'custom-defined-header-value',
common: {
'a-laihua-defined-key': 'a customized value'
'common-defined-key-b': 'custom value: for all methods'
},
post: {
'post-custom-key': 'custom value: only for post method'
},
get: {
'get-custom-key': 'custom value: only for get method'
}
}
}
......
// 移除全局拦截器
// 如果设置了全局拦截器,想取消实例中发出的请求,必须先移除全局拦截器,实例中配置的config.cancelToken属性才会生效
import axios from 'axios'
import setConfig from '@/plugins/axios/axios.setConfig.js'
import handleResponse from '@/plugins/axios/axios.handleResponse.js'
import handleError from '@/plugins/axios/axios.handleError.js'
import setConfig from '@/plugins/axios/axios.setConfig.js'
// import store from '@/store/index'
// import router from '@/router/index.js'
// import { Message } from 'element-ui'
// const showTip = (tip)=>{
// Message({
// type: 'warning',
// message: tip || '请求出错啦',
// duration: 1500
// })
// }
/**
* pureRequest是只在axios基础上更改了请求配置。
* intactRequest是只在axios基础上更改了请求配置。
* 而request是基于axios创建的实例,实例只有常见的数据请求方法,没有axios.isCancel/ axios.CancelToken等方法,
* 也就是没有**取消请求**和**批量请求**的方法。
* 所以如果需要在实例中调用取消某个请求的方法(例如取消上传),请用pureRequest。
* 所以如果需要在实例中调用取消某个请求的方法(例如取消上传),请用intactRequest。
*/
let pureRequest = setConfig(axios)
let request = setConfig(axios.create())
let intactRequest = setConfig(axios)
let request = setConfig(intactRequest.create())
// 请求中的api
let pendingPool = new Map()
......@@ -24,9 +28,9 @@ let pendingPool = new Map()
/**
* 请求拦截
*/
const requestInterceptors = request.interceptors.request.use(
const requestInterceptorId = request.interceptors.request.use(
(config) => {
// 用于请求响应异常拦截器中获取请求信息,后在pendingPool中将其删除,否则异常的请求无法再发起
// 对于异常的响应也需要在pendingPool中将其删除,但响应拦截器中的异常响应有些获取不到请求信息,这里将其保存在实例上
request.config = Object.assign({}, config)
// 在发送请求之前做些什么
// config.headers.common['cookie-id'] = cookieId
......@@ -38,25 +42,25 @@ const requestInterceptors = request.interceptors.request.use(
(err) => {
console.log('请求拦截err:', err)
// 对请求错误做些什么
Promise.reject(err)
return Promise.reject(err)
}
)
/**
* 响应拦截
*/
const responseInterceptors = request.interceptors.response.use(
const responseInterceptorId = request.interceptors.response.use(
(response) => {
const { config } = response
pendingPool.delete(config.url)
// console.log('响应response suc:', response)
// showTip(err.message)
return Promise.resolve(handleResponse(response))
},
// 对异常响应处理
(err) => {
const { config } = request
// 当响应异常,并且不是请求被取消的异常,才会将这个请求从pendingPool中删除
// 异常响应删除需要加一个判断:是否为请求被取消的异常,如果不是才会将这个请求从pendingPool中删除。
// 否则会出现一种情况:网速非常慢的情况下,在网速非常慢的情况下多次重复发送同一个请求,第一个请求还在pending状态中,
// 第二个请求发不出去会直接被cancel掉进入到异常响应,然后从pendignPool中删除,第三次请求发出的时候就无法正确判断这个请求是否还是pending状态会正常发出
if (!axios.isCancel(err)) pendingPool.delete(config.url)
......@@ -89,29 +93,34 @@ const responseInterceptors = request.interceptors.response.use(
err.message = '连接服务器失败!'
}
}
// showTip(err.message)
return Promise.reject(err)
}
)
// 移除全局的请求拦截器
function removeRequestInterceptors() {
request.interceptors.request.eject(requestInterceptors)
function removeRequestInterceptor() {
request.interceptors.request.eject(requestInterceptorId)
}
// 移除全局的响应拦截器
function removeResponseInterceptors() {
request.interceptors.response.eject(responseInterceptors)
function removeResponseInterceptor() {
request.interceptors.response.eject(responseInterceptorId)
}
/**
* // 清除所有pending状态的请求
* @param {Array} whiteList 白名单,里面pending状态的请求不会被取消
* 返回值 被取消了的
* 清除所有pending状态的请求
* @param {Array} whiteList 白名单,里面的请求不会被取消
* 返回值 被取消了的api请求
*/
function clearPendingPool(whiteList = []) {
if (!pendingPool.size) return
// const pendingUrlList = [...pendingPool.keys()].filter((url) => !whiteList.includes(url))
const pendingUrlList = Array.from(pendingPool.keys()).filter((url) => !whiteList.includes(url))
if (!pendingUrlList.length) return
pendingUrlList.forEach((pendingUrl) => {
// 清除掉所有非全局的pending状态下的请求
if (!pendingPool.get(pendingUrl).global) {
......@@ -119,16 +128,16 @@ function clearPendingPool(whiteList = []) {
pendingPool.delete(pendingUrl)
}
})
console.log('pendingUrlList:', pendingUrlList)
return pendingUrlList
}
request.removeRequestInterceptors = removeRequestInterceptors
request.removeResponseInterceptors = removeResponseInterceptors
request.removeRequestInterceptor = removeRequestInterceptor
request.removeResponseInterceptor = removeResponseInterceptor
request.clearPendingPool = clearPendingPool
// export default{
// pureRequest,
// intactRequest,
// request
// }
export { pureRequest, request }
export { intactRequest, request }
......@@ -61,6 +61,7 @@
</template>
<script>
import axios from 'axios'
export default {
data() {
return {
......@@ -73,6 +74,9 @@ export default {
},
created() {},
async mounted() {
this.getMethod2()
console.log('Object.keys(this.$request):', Object.keys(this.$request))
console.log('Object.keys(this.$request):', Object.keys(this.$intactRequest))
// let xx = await this.$api.getBanner(
// { pageSize: 20, pIndex: 2 },
// {
......@@ -84,13 +88,13 @@ export default {
// console.log('eee:',eee)
// })
// console.log('vv:', vv)
this.$api.getBanner({})
this.$api.getBanner({}, { timeout: 1 })
this.$api.login({ account: '18038018084', psw: '123456' })
// this.$api.getBanner({})
// this.$api.getBanner({}, { timeout: 1 })
// this.$api.login({ account: '18038018084', psw: '123456' })
},
methods: {
async aaa() {
// this.$request.removeRequestInterceptors()
// this.$request.removeRequestInterceptor()
// let CancelToken = this.$request.CancelToken
// this.source = CancelToken.source()
let params = {
......@@ -105,7 +109,7 @@ export default {
// cancelToken: this.source.token
})
.catch((err) => {
console.log('实例请求出错:', err, err.message)
console.log('请求出错:', err, err.message)
})
console.log('result:', result)
},
......@@ -117,8 +121,8 @@ export default {
},
// 实例中取消请求写法1
async ccc() {
this.source1 = this.$pureRequest.CancelToken.source()
let result = await this.$pureRequest
this.source1 = this.$intactRequest.CancelToken.source()
let result = await this.$intactRequest
.get('/home/banner', {
cancelToken: this.source1.token
})
......@@ -130,9 +134,9 @@ export default {
},
// 实例中取消请求写法2
async ccc1() {
this.$pureRequest
this.$intactRequest
.get('/home/banner', {
cancelToken: new this.$pureRequest.CancelToken((c) => (this.cancelFn = c))
cancelToken: new this.$intactRequest.CancelToken((c) => (this.cancelFn = c))
})
.then((data) => {
console.log('data:', data)
......@@ -155,11 +159,11 @@ export default {
// get写法2
async getMethod2() {
let params = {
a: 2,
a: 22,
type: 1,
category: 18
}
let result = await this.$request({
let result = await this.$request.request({
method: 'GET',
url: '/home/banner',
params: params
......
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