Commit 6cdefb37 authored by lipengcheng 's avatar lipengcheng

feat: 取消axios

parent e601f107
......@@ -14,15 +14,8 @@ export default {
return this.$route.meta.layout || 'default-layout'
}
},
async created() {
this.request()
},
methods: {
async request() {
let result = await this.$http.get('/home/banner?type=1&category=18')
console.log('result:', result)
}
}
async created() {},
methods: {}
}
</script>
......
import axios from 'axios'
import handleStatus from '@/plugins/handleStatus.js'
// import store from '@/store/index'
// import router from '@/router/index.js'
/**
* 默认配置
*/
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'
/**
* 请求拦截
*/
axios.interceptors.request.use(
(config) => {
// 在发送请求之前做些什么
// config.headers.common['cookie-id'] = cookieId
return config
},
(err) => {
// 对请求错误做些什么
Promise.reject(err)
}
)
/**
* 响应拦截
*/
axios.interceptors.response.use(
(response) => {
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
import axios from 'axios'
import handleStatus from '@/plugins/handleStatus.js'
// import store from '@/store/index'
// import router from '@/router/index.js'
......@@ -9,8 +10,11 @@ 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'
// 请求拦截
/**
* 请求拦截
*/
axios.interceptors.request.use(
(config) => {
// 在发送请求之前做些什么
......@@ -22,73 +26,17 @@ axios.interceptors.request.use(
Promise.reject(err)
}
)
// 处理响应错误码
const checkStatus = (response) => {
const status = response.status
// 如果http响应状态码response.status正常,则直接返回数据
if ((status >= 200 && status < 300) || status === 304) {
return response.data
} else {
// 判断后端返回的code
let errMsg = ''
const code = parseInt(response.data && response.data.code)
console.log('code:', code)
switch (code) {
case 400:
break
case 4001:
if (process.server) return
errMsg = '登录设备数量超出限制'
// store.commit('savehttpResult', { res: response.data })
break
case 403:
errMsg = '未登录'
// store.commit('changeLogin', {})
break
case 412:
errMsg = '未找到有效session'
break
case 408:
errMsg = '请求超时'
break
case 500:
errMsg = '服务器内部错误'
break
case 501:
errMsg = '服务未实现'
break
case 502:
errMsg = '网关错误'
break
case 503:
errMsg = '服务不可用'
break
case 504:
errMsg = '网关超时'
break
case 505:
errMsg = 'HTTP版本不受支持'
break
default:
// errMsg = err.response.data.msg
break
}
console.log('errMsg:', errMsg)
return {
code,
errMsg
}
}
}
// 响应拦截
/**
* 响应拦截
*/
axios.interceptors.response.use(
(response) => Promise.resolve(checkStatus(response)),
(response) => {
return Promise.resolve(handleStatus(response))
},
// 对响应错误做点什么
(err) => {
console.log('响应错误拦截err:', err)
// 对响应错误做点什么
// 错误信息err传入isCancel方法,可以判断请求是否被取消
if (axios.isCancel(err)) {
throw new axios.Cancel('cancel request')
} else {
......
import axios from 'axios'
// let baseurl = require('../../static/js/config.js').default; // 引入接口地址
// let axios = Axios.create(Object.assign(Axios.defaults, {
// baseURL: process.env.VUE_APP_BASEURL,
// timeout: 10000,
// headers: {
// 'Content-Type': 'application/json;charset=UTF-8',
// 'a-laihua-defined-key': 'a customized value',
// common: {
// 'b-laihua-defined-key': 'b customized value'
// }
// }
// }))
const myHttp = {}
......
// 参考:https://juejin.im/post/6844904152833736712#heading-5
import Axios from 'axios'
import handleStatus from '@/plugins/handleStatus.js'
const baseURL = '/webapi' // 后台baseUrl
const axios = Axios.create({
baseURL: baseURL,
timeout: 30000
})
const pending = [] // 声明一个数组用于存储每个ajax请求的队列
const cancelToken = Axios.CancelToken // 初始化取消请求的构造函数
/**
* @param {请求体信息} config
* @param {直接执行的cancel函数,执行即可取消请求} f
*/
const removePending = (config, f) => {
const flagUrl = config.url + '&' + config.method // 每次请求存储在请求中队列的元素关键值,例如:一个地址为books/create的post请求处理之后为:"books/create&post"
// 当前请求存在队列中,取消第二次请求
if (pending.includes(flagUrl)) {
if (f) {
// f为实例化的cancelToken函数
f('取消了')
} else {
pending.splice(pending.indexOf(flagUrl), 1) // cancelToken不存在,则从队列中删除该请求
}
} else {
// 当前请求不在队列中,就加进队列
if (f) {
pending.push(flagUrl)
}
}
}
// 添加请求拦截器
axios.interceptors.request.use(
(config) => {
// 由于表单提交都使用post请求,此处只对post做处理;具体情况要结合业务需要
config.cancelToken = new cancelToken((c) => {
removePending(config, c)
})
return config
},
(error) => {
return Promise.reject(error)
}
)
axios.interceptors.response.use(
(response) => {
removePending(response.config)
return Promise.resolve(handleStatus(response))
},
// 对响应错误做点什么
(err) => {
console.log('响应错误拦截err:', err)
return Promise.reject(err)
}
)
export default axios
// https://mp.weixin.qq.com/s/v7ku2KYAVW0r4Lmui4JNGA
import axios from 'axios'
import handleStatus from '@/plugins/handleStatus.js'
// import store from '@/store/index'
// import router from '@/router/index.js'
/**
* 默认配置
*/
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'
let pendingAjax = []
const fastClickMsg = '数据请求中,请稍后'
const CancelToken = axios.CancelToken
const removePendingAjax = (config, c) => {
const url = config.url
const index = pendingAjax.findIndex((i) => i === url)
if (index > -1) {
c ? c(fastClickMsg) : pendingAjax.splice(index, 1)
} else {
c && pendingAjax.push(url)
}
}
/**
* 请求拦截
*/
axios.interceptors.request.use(
(config) => {
// 在发送请求之前做些什么
// config.headers.common['cookie-id'] = cookieId
config.cancelToken = new CancelToken((c) => {
removePendingAjax(config, c)
})
return config
},
(err) => {
// 对请求错误做些什么
Promise.reject(err)
}
)
/**
* 响应拦截
*/
axios.interceptors.response.use(
(response) => {
removePendingAjax(response.config)
return Promise.resolve(handleStatus(response))
},
// 对响应错误做点什么
(err) => {
console.log('响应错误拦截err:', err)
// 请求被取消
if (axios.isCancel(err)) {
throw new axios.Cancel('cancel requesttt')
} else {
console.log('网络请求失败,请重试:')
}
return Promise.reject(err)
}
)
export default axios
import Axios from 'axios'
import handleStatus from '@/plugins/handleStatus.js'
// import store from '@/store/index'
// import router from '@/router/index.js'
/**
* 默认配置
*/
// Object.assign(axios.defaults, {
// baseURL: process.env.VUE_APP_BASEURL,
// timeout: 10000,
// headers: {
// 'Content-Type': 'application/json;charset=UTF-8',
// 'a-laihua-defined-key': 'a customized value',
// common: {
// 'b-laihua-defined-key': 'b customized value'
// }
// }
// })
let axios = Axios.create(
Object.assign(Axios.defaults, {
baseURL: process.env.VUE_APP_BASEURL,
timeout: 10000,
headers: {
'Content-Type': 'application/json;charset=UTF-8',
'a-laihua-defined-key': 'a customized value',
common: {
'b-laihua-defined-key': 'b customized value'
}
}
})
)
// 这样处理,实例axios上有CancelToken方法
// 但是没有axios.isCancel等其他方法
// 通过Axios.create()方法创建的axios实例只有指定的get/post等数据请求方法
axios.CancelToken = Axios.CancelToken
/**
* 请求拦截
*/
axios.interceptors.request.use(
(config) => {
console.log('config:', config)
// 在发送请求之前做些什么
// config.headers.common['cookie-id'] = cookieId
return config
},
(err) => {
// 对请求错误做些什么
Promise.reject(err)
}
)
/**
* 响应拦截
*/
axios.interceptors.response.use(
(response) => {
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
// https://juejin.im/post/6844903905625653262
import axios from 'axios'
// 用于存储目前状态为pending的请求标识信息
let pendingRequest = []
/**
* 请求的拦截处理
* @param config - 请求的配置项
*/
const handleRequestIntercept = (config) => {
// 区别请求的唯一标识,这里用方法名+请求路径
// 如果一个项目里有多个不同baseURL的请求
// 可以改成`${config.method} ${config.baseURL}${config.url}`
const requestMark = `${config.method} ${config.url}`
// 找当前请求的标识是否存在pendingRequest中,即是否重复请求了
const markIndex = pendingRequest.findIndex((item) => {
return item.name === requestMark
})
// 存在,即重复了
if (markIndex > -1) {
// 取消上个重复的请求
pendingRequest[markIndex].cancel()
// 删掉在pendingRequest中的请求标识
pendingRequest.splice(markIndex, 1)
}
// (重新)新建针对这次请求的axios的cancelToken标识
const CancelToken = axios.CancelToken
const source = axios.CancelToken.source()
config.cancelToken = source.token
// 设置自定义配置requestMark项,主要用于响应拦截中
config.requestMark = requestMark
// 记录本次请求的标识
pendingRequest.push({
name: requestMark,
cancel: source.cancel,
routeChangeCancel: config.routeChangeCancel // 可能会有优先级高于默认设置的routeChangeCancel项值
})
return config
}
/**
* 响应的拦截处理
* @param config - 请求的配置项
*/
const handleResponseIntercept = (config) => {
// 根据请求拦截里设置的requestMark配置来寻找对应pendingRequest里对应的请求标识
const markIndex = pendingRequest.findIndex((item) => {
return item.name === config.requestMark
})
// 找到了就删除该标识
markIndex > -1 && pendingRequest.splice(markIndex, 1)
}
/**
* 创建axios实例
* @param {String} url - 访问后台的主url
*/
const createAxiosInstance = (baseUrl) => {
let instance = axios.create({
baseURL: '/webapi'
})
// 默认把请求视为切换路由就会把pending状态的请求取消,false为不取消
instance.defaults.routeChangeCancel = true
// 请求拦截
instance.interceptors.request.use(handleRequestIntercept, (error) => Promise.reject(error))
// 响应拦截
instance.interceptors.response.use(
(res) => {
handleResponseIntercept(res.config)
// 其实更多情况下你执行获取res.data
// 可以return res.data;
return res
},
(error) => {
let errorFormat = {}
const response = error.response
// 请求已发出,但服务器响应的状态码不在 2xx 范围内
if (response) {
handleResponseIntercept(response.config)
// 设置返回的错误对象格式(按照自己项目实际需求)
errorFormat = {
status: response.status,
data: response.data
}
}
// 如果是主动取消了请求,做个标识
if (axios.isCancel(error)) {
errorFormat.selfCancel = true
}
// 其实还有一个情况
// 在设置引发错误的请求时,error.message才是错误信息
// 但我觉得这个一般是脚本错误,我们项目提示也不应该提示脚本错误给用户看,一般都是我们自定义一些默认错误提示,如“创建成功!”
// 所以这里不针对此情况做处理。
return Promise.reject(errorFormat)
}
)
// 还有一些其他你想要的axios实例设置
// ...
return instance
}
const http = createAxiosInstance()
// 其他配置
// ...
export { pendingRequest }
export default http
// 处理响应错误码
export default (response) => {
const status = response.status
// 如果http响应状态码response.status正常,则直接返回数据
if ((status >= 200 && status < 300) || status === 304) {
return response.data
} else {
// 判断后端返回的code
let errMsg = ''
const code = parseInt(response.data && response.data.code)
console.log('code:', code)
switch (code) {
case 400:
break
case 4001:
if (process.server) return
errMsg = '登录设备数量超出限制'
// store.commit('savehttpResult', { res: response.data })
break
case 403:
errMsg = '未登录'
// store.commit('changeLogin', {})
break
case 412:
errMsg = '未找到有效session'
break
case 408:
errMsg = '请求超时'
break
case 500:
errMsg = '服务器内部错误'
break
case 501:
errMsg = '服务未实现'
break
case 502:
errMsg = '网关错误'
break
case 503:
errMsg = '服务不可用'
break
case 504:
errMsg = '网关超时'
break
case 505:
errMsg = 'HTTP版本不受支持'
break
default:
// errMsg = err.response.data.msg
break
}
console.log('errMsg:', errMsg)
return {
code,
errMsg
}
}
}
// 全局vuex信息
// getter调用示例:this.$store.getters['authed']
import axios from '@/plugins/axios'
const state = {
_authed: false
}
......@@ -11,7 +13,12 @@ const getters = {
const mutations = {}
const actions = {}
const actions = {
async testAction(ctx, paylaod) {
let result = await axios.get('/home/banner?type=1&category=18')
console.log('result:', result)
}
}
export default {
state,
......
<template>
<div class="comp-bao2">
<h1>home</h1>
<h1 @click="ttt()">
home
</h1>
<div
a="dfsfsdfdsfsdffsdfsdfsdfsdfsfsdf"
b="dfsfsdfdsfsfsdfsdfsdfsdfsfsdf"
......@@ -21,17 +23,53 @@
aria-hidden="true">
<use xlink:href="#icon-14"></use>
</svg>
<div
style="width:50px;height: 20px;"
@click="aaa">
1111
</div>
<div
style="width:50px;height: 20px;"
@click="bbb">
2222
</div>
</div>
</template>
<script>
export default {
data() {
return {}
return {
source: {},
cancelObj: {}
}
},
created() {},
mounted() {},
methods: {}
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
})
})
console.log('this.cancelObj:', this.cancelObj)
console.log('result:', result)
},
bbb() {
console.log('this.source:', this.source)
// this.source.cancel('333333333')
this.cancelObj.cancel()
}
}
}
</script>
......
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