刷新

45 阅读1分钟

// 封装axios import { Toast } from 'antd-mobile' import axios, { AxiosError } from 'axios' import store from '@/store' import { getToken, setToken } from './storage' import { logout } from '@/store/actions/login' import history from './history' export const baseURL = '/api' // export const baseURL = 'geek.itheima.net' const instance = axios.create({ baseURL: baseURL + /v1_0/, timeout: 5000, })

// 这个实例专门用于刷新token // axios的写法:baseURL可以分开写 和url const instance2 = axios.create({ baseURL: baseURL + /v1_0/, timeout: 5000, })

// 添加请求拦截器 instance.interceptors.request.use( function (config) { const token = getToken() if (token.token && config.headers) { config.headers.Authorization = Bearer ${token.token} } return config }, function (error) { // 对请求错误做些什么 return Promise.reject(error) } )

// 添加响应拦截器 instance.interceptors.response.use( function (response) { // 对响应数据做点什么 return response }, async function (error: AxiosError<{ message: string }>) { if (!error.response) { // 由于网络繁忙导致的 Toast.show('网络繁忙,稍后再试') return Promise.reject(error) } console.dir(error) // 1. 判断是否401错误 if (error.response.status === 401) { // 2. 是401错误 没有token token过期了 const token = getToken() if (token.token && token.refresh_token) { try { // 3. 有token, token过期, 尝试去刷新token,注意需要使用原始的axios来刷新, // 因为响应拦截器被添加了token,这里要发送的是refresh_token const res = await instance2({ url: '/authorizations', method: 'put', headers: { Authorization: Bearer ${token.refresh_token}, }, }) console.log(res) // 4. 刷新token成功,将新的token保存到redux中 store.dispatch({ type: 'login/login', payload: { // 这里要根据后端返回的情况 refresh_token: token.refresh_token是用的上一次的,所以如果过期,那么15天以后还是需要重新登录 // 所以如果说后端可以给一个新的refreshtoken,就可以实现一直登录 token: res.data.data.token, refresh_token: token.refresh_token, }, }) setToken({ token: res.data.data.token, refresh_token: token.refresh_token, })

      // 在登录那里,401了,拿到了token,返回空就会报错,所以要返回一个。因为Token已经没问题了,重新发送请求拿到用户信息
      console.dir(error) //拿到所有信息
      return instance(error.config) //所有的url method都在error.config
    } catch {
      // 刷新失败
      // 1. 移除token
      store.dispatch(logout())
      // 2. 跳转到登录页

      // window.location.href = '/login'
      history.replace('/login', { from: history.location.pathname })
      Toast.show('登录信息失效')
      return Promise.reject(error)
    }
  } else {
    // 401错误是没有token导致的
    // console.log('跳转到登录页')
    // window.location.href = '/login'
    history.replace('/login', { from: history.location.pathname })
  }
}

Toast.show(error.response.data.message)
return Promise.reject(error)

} )

export default instance