举例描述一下业务场景:当token过期,需要用户重新登录时,需要在页面弹框提示重新登录。
显然这个重新登录的提示弹框的逻辑是在响应拦截器中加的,我的代码如下:(只提供部分代码)
1 // 返回拦截器 2 service.interceptors.response.use( 3 response => { 4 if (response.data.status === -1) { 5 Message({ 6 message: response.data.message, 7 type: 'error', 8 duration: 3 * 1000 9 }) 10 } 11 if (response.headers['content-disposition']) { 12 return response 13 } 14 return response.data 15 }, 16 error => { 17 if (error && error.response) { 19 switch (error.response.status) { 20 case 401: 21 if (error.response.data.code) { 23 MessageBox.confirm(error.response.data.errors || 'Error', '确定重新登录', { 24 confirmButtonText: '确定', 25 type: 'warning' 26 }).then(() => { 27 store.dispatch('user/resetToken').then(() => { 29 router.push('/login') 30 }) 31 }) 33 } 34 break;48 } 49 } else { 50 // error.message = '连接失败...' 51 } 52 return Promise.reject(error) 53 } 54 )
问题详细描述:当在token过期的页面如果同时发出多个请求时,就会对应出现多个弹框(注意:我这里用的是elementui提供的messageBox,故弹框是在触发确认或取消按钮按照顺序弹出的。)
这样的展示显示用户体验效果不好,当401时应该出现一次弹框,点击确认直接进入登录页,不需要再出现多余的弹框。那这个问题如何修改呢?
解决方法:
加一个全局变量flag,用来标识记录是否触发过messageBox中的按钮。false是未出现过弹框,true代表出现过一次。在做switch匹配前判断flag是否为true,是则中断执行,否则继续执行,执行完messageBox代码后,需要将flag设为true,且需要注意此时还要加个定时器还原flag的初始值为false。因为取消后如果不把flag还原,则不会再出现提示弹框。以下是代码:
1 let flag = false 3 // 返回拦截器 4 service.interceptors.response.use( 5 ... 6 error => { 7 if (error && error.response) { 8 if (flag) return 9 switch (error.response.status) { 10 case 401: 11 if (error.response.data.code) { 13 MessageBox.confirm(error.response.data.errors || 'Error', '确定重新登录', { 14 confirmButtonText: '确定', 15 type: 'warning' 16 }).then(() => { 17 store.dispatch('user/resetToken').then(() => { 18 // location.reload() 19 router.push('/login') 20 }) 21 })
flag = true 22 setTimeout(() => { 23 flag = false 24 }, 2000); 25 } 26 break; 27 ... 28 } 29 } else { 30 // error.message = '连接失败...' 31 } 32 return Promise.reject(error) 33 } 34 )
标签:vue,登录,弹框,flag,error,data,response From: https://www.cnblogs.com/heisetianshi/p/17842153.html