mounted内发起的请求被axios拦截器重试后,如何获取返回数据更新页面
问题根因
你当前的axios响应拦截器对401刷新逻辑的异步处理存在缺陷:
- 刷新token的
axios.post请求没有返回对应的Promise对象,触发401时拦截器会直接执行末尾的return Promise.reject(error),原getList请求直接进入catch分支 - 重试原请求成功后的结果没有传递回原请求的
then回调,所以this.items始终没有被赋值,页面自然不会更新 - 额外的小错误:重试时给原请求加了不必要的
grant_type头,同时操作_retry标记的对象写错了
修复方案
第一步:修改axios响应拦截器代码
axios.interceptors.response.use( function (response) { return response }, async function (error) { const originalRequest = error.config // 加可选链避免response不存在时报错 if (error.response?.status === 401 && !originalRequest._retry) { // 给当前待重试的请求加标记,避免无限重试 originalRequest._retry = true sessionStorage.removeItem('access-token') try { const headers = { grant_type: 'refresh_token', Authorization: sessionStorage.getItem('refresh-token'), } // 等待刷新token请求完成 const refreshRes = await axios.post('/api/v1/users/refresh_token', {}, { headers }) const token = refreshRes.data.data sessionStorage.setItem('access-token', token) // 给原请求更新新token originalRequest.headers['Authorization'] = token // 重试原请求,把结果返回给原请求的调用链 return axios.request(originalRequest) } catch (refreshError) { console.log(refreshError) alert('blablabla.') // 刷新失败也返回错误,让原请求可以捕获 return Promise.reject(refreshError) } } return Promise.reject(error) }, )
可选优化:调整getList写法(非必须,仅提升可读性)
async getList() { try { const response = await axios.get('/api/v1/requests/all', { params: { userId: this.$store.state.userInfo.id, }, }) const moment = require('moment') response.data.data.forEach(item => { item.createdAt = moment(item.createdAt).format('YYYY-MM-DD HH:mm:ss') }) this.items = response.data.data } catch (error) { console.log(error) } }
修改后重试请求的结果会正常传递回getList的回调,this.items会被正确赋值,页面列表就可以正常渲染了。
内容的提问来源于stack exchange,提问作者daehyeon
相关产品推荐
相关产品推荐

