axios拦截器token过期挂起请求,弹框重新登录后重发请求无法获取到值

import axios from "axios";
import {
  Message,
  MessageBox
} from "element-ui";

import {
  deleteToken,
  getToken
} from "@/libs/util";

import router from "../router/index";
import store from "../store";

let retryRequest = []; //存放token過期的請求
let isRefresh = false;
class HttpRequest {
  constructor(baseUrl = '') {
    this.baseUrl = baseUrl
    this.queue = {}
  }
  getInsideConfig() {
    const config = {
      baseURL: this.baseUrl,
      headers: {
        //
      }
    }
    return config
  }
  destroy(url) {
    delete this.queue[url]
    if (!Object.keys(this.queue).length) {
      // Spin.hide()
    }
  }
  interceptors(instance, url) {
    // 请求拦截
    instance.interceptors.request.use(
      config => {
        config.headers.Authorization = 'Bearer ' + getToken();
        // 新增全局的loading...
        if (!Object.keys(this.queue).length) {
          // Spin.show() // 不建议开启,因为界面不友好
        }
        this.queue[url] = true
        return config
      },
      error => {
        return Promise.reject(error)
      }
    )
    // 响应拦截
    instance.interceptors.response.use(
      res => {
        if (res && res.data && res.data.code === 203) {
          if (!isRefresh && router.currentRoute.name !== 'login') {
            isRefresh = true;
            MessageBox.prompt('', '您长时间未活动请重新输入密码', {
              inputType: 'password',
              inputPattern: /\S/,
              inputErrorMessage: '请输入正确密码!',
              confirmButtonText: '确定',
              showClose: false,
              closeOnPressEscape: false,
              closeOnClickModal: false,
              center: true,
               callback: function (action, instance) {
                if(action === 'confirm') {       
                    new Promise((resolve,reject)=>{// 点击确定,进行的异步操作
                      let obj = {}
                      obj.userid = JSON.parse(sessionStorage.getItem("userInfo")).userid;
                      obj.password = instance.inputValue;
                      return store.dispatch('handleLogin', obj).then(data => {
                        console.log(data.token)
                       retryRequest.forEach(cb => {
                          cb(data.token)
                        })
                        isRefresh = false;
                        retryRequest = [];
                        let url = res.config.url;
                        if (url.indexOf('/go') === 0) {
                          url = url.slice(3)
                        }
                        res.config.headers.Authorization = 'Bearer ' + data.token
                        res.config.url = url;
                        return axios(res.config)
                      })
                    }).then((error) => {
                        console.log(error);
                    })
                }else {
                  MessageBox.close()
                  deleteToken()
                  router.replace({
                    path: '/login',
                  })
                }
            }
            })
          } else {
            Message.error(res.data.message || "请求失败")
            return new Promise((resolve) => {
              retryRequest.push((token) => {
                let url = res.config.url;
                if (url.indexOf('/go') === 0) {
                  url = url.slice(3)
                }
                res.config.url = url;
                return resolve(axios(res.config))
              })
            })
          }
        }
        const {
          data,
          status
        } = res
        return {
          data,
          status //这里是有值的,但是页面上获取不到值
        }
      },
      error => {
        this.destroy(url)
        return Promise.reject(error)
      }
    )
  }
  request(options) {
    const instance = axios.create()
    options = Object.assign(this.getInsideConfig(), options)
    this.interceptors(instance, options.url)
    return instance(options)
  }
}
export default HttpRequest
阅读 3.4k
1 个回答

image.png

这里这个 promise 你没有等待。其实你可以打个日志看一下,肯定是先输出的回调,后输出的登陆

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题