<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
axios向伺服器端傳送請求時,有兩種情況會出現401狀態碼(unauthorized未授權):
1. 伺服器端要求傳遞token資訊,而實際傳送請求時沒有傳遞。
2. 傳送請求時有傳遞token到達伺服器端,但由於時間比較久,這個token在伺服器中已經過期了(伺服器儲存token有效期時間為2個小時)。
總之,伺服器端有些api介面要求傳遞token,token失效或沒有傳遞,就會報401錯誤。
1. 在axios請求攔截器中做token傳遞操作。
2. 可以這樣設定,在axios響應攔截器中判斷請求狀態如果是401,就強制使用者重新登入系統。
第2種情況處理實現:
在axios的響應攔截器中,判斷錯誤碼等於401就強制登入(utils/ax.js)
// 引入路由 import router from '@/router' // 設定響應攔截器 axios.interceptors.response.use(function (response) { // 正常響應處理 return response }, function (error) { // 非正常響應處理(包括401) // console.dir(error) // 物件: config request response isAxiosError toJSON if (error.response.status === 401) { // token失效(token在伺服器端已經失效了,2個小時時效) // 強制使用者重新登入系統,以重新整理伺服器端的token時效 router.push('/login') // 不要給做錯誤提示了 return new Promise(function () {}) // 空的Promise物件,沒有機會執行catch,進而不做錯誤提示了 } // return new Promise((resolve,reject)=>{ // reject('獲得文章失敗!') // }) return Promise.reject(error) })
注意:
1. 路由物件.push(xxx) 可以實現程式設計式導航。
2. 路由物件:在元件中是 this.$router ,在main.js/ax.js檔案中就是router物件(需要import匯入)。
模擬伺服器端token失效步驟:
1. 刪除使用者端sessionStorage資料。
2. 暫時遮蔽守衛程式碼(開發完畢再開啟)。
axios向伺服器端傳送請求時有兩種情況會出現401狀態碼(unauthorized未授權):
1. 伺服器端要求傳遞token資訊,而實際沒有傳遞。
2. 有傳遞token到達伺服器端,但由於時間比較久,這個token在伺服器中已經過期了(伺服器儲存token有效期時間為2個小時)。
總之,伺服器端有些api介面要求傳遞token,token失效或沒有傳遞,就會報401錯誤。
1. 第1種情況,可以在axios請求攔截器中做token傳遞操作。
2. 第2種情況,之前是這樣處理的,在axios響應攔截器中判斷請求狀態如果是401,就強制使用者重新登入系統
這樣處理使用者體驗非常不好,現在做一次升級優化處理。
伺服器端返回兩個祕鑰資訊,它們在伺服器端都有使用時效:
token
有效期2小時。refresh_token
有效期14天,refresh_token用於在token過期後,重新獲取並重新整理token時效使用的。針對第2種401狀態碼處理步驟為:
1. 判斷refresh_token是否存在
不存在就直接重新登入。
存在,axios發起請求,帶著refresh_token請求伺服器端,獲取新token出來:
成功:對vuex和localStorage進行token資訊更新。
失敗:清空無效使用者資訊,直接重新登入。
// 響應攔截器 (響應成功:剝離無效資料,響應失敗:重新整理token) instance.interceptors.response.use(res => { // 將來獲取資料:res.data.data 麻煩 // 想要結果:data 即可 try { return res.data.data } catch (e) { return res } }, async err => { try { // 目的:重新整理token if (err.response && err.response.status === 401) { // 未登入 跳轉登入頁面 阻止程式執行 const { user } = store.state // 如果沒有token沒登入 如果沒有refresh_token無法重新整理token if (!user.token || !user.refresh_token) { router.push('/login') return Promise.reject(err) } // 重新整理token,發請求,沒有設定的axios,自己設定refresh_token const res = await axios({ url: 'http://ttapi.research.itcast.cn/app/v1_0/authorizations', method: 'put', headers: { Authorization: `Bearer ${user.refresh_token}` } }) // token獲取 res.data.data.token // 更新 vuex 和 本地 token store.commit('setUser', { token: res.data.data.token, refresh_token: user.refresh_token }) // 繼續傳送剛才錯誤的請求 // instance({之前錯誤的請求設定}) // err錯誤物件 包含(response 響應物件 |config 請求設定) return instance(err.config) } } catch (e) { // exception 異常 // 重新整理token失敗 router.push('/login') return Promise.reject(e) } return Promise.reject(err) })
演示程式碼:promise錯誤處理:
import store from '@/store' // 引入vuex中的store範例 import router from '@/router' // 引入路由物件範例 …… // 響應攔截器 instance.interceptors.response.use( function (response) { try { // 返回具體有價值的業務資料 return response.data.data } catch (error) { return response.data } }, async function (error) { // 響應有錯誤,有可能錯誤狀態碼為401 if (error.response && error.response.status === 401) { // 定義登入路由物件 let toPath = { name: 'login', query: { redirectUrl: router.currentRoute.path } } // 跳轉物件 // 如果refresh_token不存在 if (!store.state.user.refresh_token) { router.push(toPath) return Promise.reject(error) } try { // 重新整理使用者token // 應該傳送一個請求 換取新的token // 這裡不應該再用instance 因為 instance會再次進入攔截器 用預設的axios let result = await axios({ method: 'put', url: 'http://ttapi.research.itcast.cn/app/v1_0/authorizations', headers: { Authorization: `Bearer ${store.state.user.refresh_token}` } }) // 獲取到新token後,就對vuex和localStorage進行更新 store.commit('updateUser', { token: result.data.data.token, // 拿到新的token之後 refresh_token: store.state.user.refresh_token // 將之前 refresh_token 14天有效期 }) return instance(error.config) // 把剛才錯誤的請求再次傳送出去 然後將promise返回 } catch (err) { // 如果錯誤 表示補救措施也沒用了(有可能refresh_token也失效了) // 應該跳轉到登入頁 並且 把廢掉的使用者資訊全都幹掉 store.commit('clearUser') // 所有的使用者資訊清空 router.push(toPath) // 跳轉到回登入頁 return Promise.reject(err) } } return Promise.reject(error) } ) ') // 所有的使用者資訊清空 router.push(toPath) // 跳轉到回登入頁 return Promise.reject(err) } } return Promise.reject(error) } )
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45