当前位置: 首页 > Web前端 > vue.js

vueaxios包取消请求

时间:2023-03-31 19:56:03 vue.js

最好的年华,没有遇到爱情,只遇到了疫情应用环境,当我们在项目中使用模糊匹配查询列表时,在输入框中输入关键字,我们会根据关键词调优界面查询数据,如果输入速度快,但界面响应不快,就会出现搜索到的数据与输入关键词不匹配的情况。这时候我们需要配置axios请求的取消无响应接口的CancelToken,直接根据最新的输入查询接口,匹配最新的结果导入axios定义需要的变量//importaxiosimportaxiosfrom'axios'...letcancelletpromiseArr={}constCancelToken=axios.CancelToken在请求拦截器中配置//取消请求if(promiseArr[config.url]){promiseArr[config.url]('operationcancelled')promiseArr[config.url]=cancel}else{promiseArr[config.url]=cancel}在get/post/put请求中配置...axios.get(url,{params:params,cancelToken:newCancelToken(c=>{cancel=c})}).then(res=>{...axios.post(url,params,{cancelToken:newCancelToken(c=>{cancel=c})}).then(res=>{completevue中axios包的代码//引入axiosimportaxiosfrom'axios'//引入qs模块序列化post类型数据,后面会提到//importqsfrom'qs'importstorefrom'@/store/index'importrouterfrom'@/router/index'//elementUi提示组件。import{Message}from'element-ui'//import{LoadingBar}from'iview'letcancelletpromiseArr={}constCancelToken=axios.CancelToken//环境切换console.log(process.env.NODE_ENV,process.env.ENV_CONFIG,'环境参数')axios.defaults.baseURL=window.location.origin//设置最大请求时长axios.defaults.timeout=50000//axios.defaults.headers.post['Content-Type']='application/x-www-form-urlencoded;charset=UTF-8'axios.defaults.headers.post['Content-Type']='application/json;charset=UTF-8'axios.defaults.headers.common['按用户信息']=localStorage.getItem('userInfo_admin')?JSON.parse(localStorage.getItem('userInfo_admin')).user_id:''axios.defaults.withCredentials=true//请求拦截器axios.interceptors.request.use(config=>{//如果不是登录界面,或者微信分享界面,需要token验证,隐私政策//if(window.location.hash.indexOf('login')===-1&&window.location.hash.indexOf('wechat-share')===-1&&window.location.hash.indexOf('private')===-1){//consttoken=store.state.userInfo.Authorization//token&&(config.headers.Authorization=token)//}//取消请求if(promiseArr[config.url]){promiseArr[config.url]('operationcancel')promiseArr[config.url]=cancel}else{promiseArr[config.url]=cancel}//在request请求的header中配置Authorization,如果登陆了,就有Authorization,设置if(store.state.userInfo&&store.state.userInfo.Authorization){consttoken=store.state.userInfo.Authorizationtoken&&(config.headers.Authorization=token)}returnconfig},error=>{Message.error({message:'请求接口错误',duration:3000})returnPromise.error(error)})//响应拦截器axios.interceptors.response.use(response=>{//如果返回状态码为200,表示接口请求成功并且可以正常获取数据//否则抛错if(response.status===200){returnPromise.resolve(response)}else{returnPromise.reject(response)}},error=>{if(error.response.status){switch(error.response.status){//401:未登录//未登录然后跳转到登录页面并携带当前页面的路径//登录成功后返回当前页面,这一步需要在登录页面进行操作case401://Message.error({//message:'Nopermission',//duration:1000//})//window.location.href=store.getters.base_url+'new-home/#/login'//router.replace({name:'login'})break//403tokenexpired//登录过期时提示用户//清空本地token,清除vuex中的token对象//跳转到登录页面case403://Message.error({//message:'登录过期,请重新登录',//duration:1000//})//清除token//localStorage.removeItem('token')//store.commit('loginSuccess',null)//跳转到登录页面,传入要浏览页面的fullPath。登录成功后跳转到要访问的页面//window.location.href=store.getters.base_url+'new-home/#/login'localStorage.clear()store.dispatch('loginOut')break//404requestdoesnotexistcase404:Message.error({message:'网络请求不存在',duration:1500})break//其他错误,直接抛出错误提示default:{//Message.error({//消息:error.response.data.message,//duration:1500//})}}returnPromise.reject(error.response)}})exportfunctionget(url,params,config){if(config){axios.defaults.headers.post['Content-Type']='multipart/form-data'}//LoadingBar.start()letphpApi=false//获取方法中使用php接口地址if(url==='/index.php/file/upload_token'||url==='/index.php/home_page/currency'||url==='/index.php/count_channel/channel_province_count'||url==='/index.php/count_channel/channel_history_count'||url==='/index.php/count_channel/channel_role_count'||url==='/index.php/count_channel/channel_newadd_count'||url==='/index.php/count_project/project_num_count'||url==='/index.php/count_project/department_count'||url==='/index.php/count_project/project_count_total'||url==='/index.php/用户/部门'||url==='/index.php/count_project/project_department_num_count'||url==='/index.php/count_project/province_count'||url==='/index.php/count_project/clue_source_count'||url==='/index.php/count_project/stage_count'||url==='/index.php/count_project/reason_count'||url==='/index.php/count_project/project_time_count'||url==='/index.php/count_project/project_time_department_count'||url==='/index.php/count_project/duban_money_count'||url==='/index.php/count_project/refuse_count'||url==='/index.php/count_project/project_evaltime_count'||url==='/index.php/count_project/accept_count'){phpApi=true}else{phpApi=false}//在线环境if(process.env.NODE_ENV==='production'){//上传tokenif(phpApi){axios.defaults.baseURL='https://api.bangying.tech/prod/pg_app_api'}else{axios.defaults.baseURL='https://www.bangying.tech/pg-api'}}else{//开发测试环境//获取上传令牌if(phpApi){axios.defaults.baseURL='https://api.bangying.tech/new_simulate/new_m_api'}else{axios.defaults.baseURL='https://mn.bangying.tech/pg-api'}}returnnewPromise(async(resolve,reject)=>{awaitaxios.get(url,{params:params,cancelToken:newCancelToken(c=>{cancel=c})}).then(res=>{resolve(res.data)//LoadingBar.finish()}).catch(err=>{reject(err.data)//LoadingBar.error()})})}exportfunctionpost(url,params,config){if(config){axios.defaults.headers.post['Content-Type']='application/x-www-form-urlencoded;charset=UTF-8'}//LoadingBar.start()console.log(window.location.hash)返回newPromise((resolve,reject)=>{//线上环境if(process.env.NODE_ENV==='production'){//php接口if(url==='/index.php/login/account'||url==='/index.php/login/wechat'||url==='/index.php/login/un_login'){axios.defaults.baseURL='https://api.bangying.tech/prod/pg_app_api'}elseif(url==='qiniu'){axios.defaults.baseURL=''url='https://qiniu.pangu.tech/'}else{//java接口axios.defaults.baseURL='https://www.bangying.tech/pg-api'}}else{//开发测试环境//如果是php接口if(url==='/index.php/login/account'||url==='/index.php/login/wechat'||url==='/index.php/login/un_login'){axios.defaults.baseURL='https://api.bangying.tech/new_simulate/new_m_api'}elseif(url==='qiniu'){axios.defaults.baseURL=''url='https://qiniu.pangu.tech/'}else{//java接口axios.defaults.baseURL='https://mn.bangying.tech/pg-api'}}axios.post(url,params,{cancelToken:newCancelToken(c=>{cancel=c})}).then(res=>{resolve(res.data)//LoadingBar.finish()}).catch(err=>{reject(err.data)//LoadingBar.error()})})}exportfunctionput(url,params){//LoadingBar.start()console.log(window.location.hash)returnnewPromise((resolve,reject)=>{//线上环境if(process.env.NODE_ENV==='production'){if(url==='/index.php/login/account'||url==='/index.php/project/up_status'){axios.defaults.baseURL='https://api.banghing.tech/prod/pg_app_api'}elseif(url==='qiniu'){axios.defaults.baseURL=''url='https://qiniu.pangu.tech/'}else{axios.defaults.baseURL='https://www.bangying.tech/pg-api'}}else{//开发测试环境if(url==='/index.php/login/account'||url==='/index.php/project/up_status'){axios.defaults.baseURL='https://api.bangying.tech/new_simulate/new_m_api'}else{axios.defaults.baseURL='https://mn.bangying.tech/pg-api'}}axios.put(url,params,{cancelToken:newCancelToken(c=>{cancel=c})}).then(res=>{resolve(res.data)//LoadingBar.finish()}).catch(err=>{reject(err.data)//LoadingBar.error()})})}exportfunctiongetAxios(){//line上层环境if(process.env.NODE_ENV==='production'){axios.defaults.baseURL='https://www.bangying.tech/pg-api'}else{//开发测试环境axios.defaults.baseURL='https://mn.bangying.tech/pg-api'}returnaxios}实践证明这样的封装是有问题的。真正的技术如下所示//introduceaxiosimportaxiosfrom'axios'...//声明一个数组,用于存储每个请求的取消函数和axios标识letpending=[]constCancelToken=axios.CancelTokenletremovePending=(config)=>{for(letpinpending){if(pending[p].u===config.url+JSON.stringify(config.data)+'&'+config.method){pending[p].f()pending.splice(p,1)}}}...//请求拦截器axios.interceptors.request.use(config=>{//取消请求removePending(config)config.cancelToken=newCancelToken((c)=>{//这里的axios标志是请求地址&request拼接的字符串method,当然你也可以选择一些其他的方式pending.push({u:config.url+JSON.stringify(config.data)+'&'+config.method,f:c})})...})...//响应拦截器axios.interceptors.response.use(response=>{...//取消响应removePending(response.config)...})这样就可以在请求和响应中拦截