/** * 封裝 axios 請求模塊 */ import axios from 'axios' import jsonBig from 'json-bigint' import store from '@/store' import router from '@/router' import { Notify } from 'vant' // axios.create 方法:復制一個 axios const request = axios.create({ baseURL: 'http://ttapi.research.itcast.cn/' // 基礎路徑 }) /** * 配置處理后端返回數據中超出 js 安全整數范圍問題 */ request.defaults.transformResponse = [function (data) { try { return jsonBig.parse(data) } catch (err) { return {} } }] // 請求攔截器 request.interceptors.request.use( function (config) { const user = store.state.user if (user) { config.headers.Authorization = `Bearer ${user.token}` } // Do something before request is sent return config }, function (error) { // Do something with request error return Promise.reject(error) } ) // 響應攔截器 request.interceptors.response.use( // 響應成功進入第1個函數 // 該函數的參數是響應對象 function (response) { // Any status code that lie within the range of 2xx cause this function to trigger // Do something with response data return response }, // 響應失敗進入第2個函數,該函數的參數是錯誤對象 async function (error) { // Any status codes that falls outside the range of 2xx cause this function to trigger // Do something with response error // 如果響應碼是 401 ,則請求獲取新的 token // 響應攔截器中的 error 就是那個響應的錯誤對象 if (error.response && error.response.status === 401) { // 校驗是否有 refresh_token const user = store.state.user if (!user || !user.refresh_token) { // router.push('/login') redirectLogin() // 代碼不要往后執行了 return } // 如果有refresh_token,則請求獲取新的 token try { const res = await axios({ method: 'PUT', url: 'http://ttapi.research.itcast.cn/app/v1_0/authorizations', headers: { Authorization: `Bearer ${user.refresh_token}` } }) // 如果獲取成功,則把新的 token 更新到容器中 console.log('刷新 token 成功', res) store.commit('setUser', { token: res.data.data.token, // 最新獲取的可用 token refresh_token: user.refresh_token // 還是原來的 refresh_token }) // 把之前失敗的用戶請求繼續發出去 // config 是一個對象,其中包含本次失敗請求相關的那些配置信息,例如 url、method 都有 // return 把 request 的請求結果繼續返回給發請求的具體位置 return request(error.config) } catch (err) { // 如果獲取失敗,直接跳轉 登錄頁 console.log('請求刷線 token 失敗', err) // router.push('/login') redirectLogin() } } else if (error.response.status === 500) { Notify('服務端異常,請稍后重試') } return Promise.reject(error) } ) function redirectLogin () { // router.currentRoute 當前路由對象,和你在組件中訪問的 this.$route 是同一個東西 router.push('/login?redirect=' + router.currentRoute.fullPath) } export default request