關(guān)于401狀態(tài)碼的含義和處理方式
401狀態(tài)碼的含義和處理
401狀態(tài)碼的含義
axios向服務(wù)器端發(fā)送請求時,有兩種情況會出現(xiàn)401狀態(tài)碼(unauthorized未授權(quán)):
1. 服務(wù)端要求傳遞token信息,而實(shí)際發(fā)送請求時沒有傳遞。
2. 發(fā)送請求時有傳遞token到達(dá)服務(wù)器端,但由于時間比較久,這個token在服務(wù)器中已經(jīng)過期了(服務(wù)器存儲token有效期時間為2個小時)。
總之,服務(wù)器端有些api接口要求傳遞token,token失效或沒有傳遞,就會報401錯誤。
401狀態(tài)碼的處理
1. 在axios請求攔截器中做token傳遞操作。
2. 可以這樣設(shè)置,在axios響應(yīng)攔截器中判斷請求狀態(tài)如果是401,就強(qiáng)制用戶重新登錄系統(tǒng)。
第2種情況處理實(shí)現(xiàn):
在axios的響應(yīng)攔截器中,判斷錯誤碼等于401就強(qiáng)制登錄(utils/ax.js)
// 引入路由
import router from '@/router'
// 配置響應(yīng)攔截器
axios.interceptors.response.use(function (response) {
? // 正常響應(yīng)處理
? return response
}, function (error) {
? // 非正常響應(yīng)處理(包括401)
? // console.dir(error) // 對象: config request response isAxiosError toJSON
? if (error.response.status === 401) {
? ? // token失效(token在服務(wù)器端已經(jīng)失效了,2個小時時效)
? ? // 強(qiáng)制用戶重新登錄系統(tǒng),以刷新服務(wù)器端的token時效
? ? router.push('/login')
? ? // 不要給做錯誤提示了
? ? return new Promise(function () {}) // 空的Promise對象,沒有機(jī)會執(zhí)行catch,進(jìn)而不做錯誤提示了
? }
? // return new Promise((resolve,reject)=>{
? // reject('獲得文章失??!')
? // })
? return Promise.reject(error)
})注意:
1. 路由對象.push(xxx) 可以實(shí)現(xiàn)編程式導(dǎo)航。
2. 路由對象:在組件中是 this.$router ,在main.js/ax.js文件中就是router對象(需要import導(dǎo)入)。
模擬服務(wù)器端token失效步驟:
1. 刪除客戶端sessionStorage數(shù)據(jù)。
2. 暫時屏蔽守衛(wèi)代碼(開發(fā)完畢再打開)。
401狀態(tài)碼升級處理
401狀態(tài)碼
axios向服務(wù)器端發(fā)送請求時有兩種情況會出現(xiàn)401狀態(tài)碼(unauthorized未授權(quán)):
1. 服務(wù)端要求傳遞token信息,而實(shí)際沒有傳遞。
2. 有傳遞token到達(dá)服務(wù)器端,但由于時間比較久,這個token在服務(wù)器中已經(jīng)過期了(服務(wù)器存儲token有效期時間為2個小時)。
總之,服務(wù)器端有些api接口要求傳遞token,token失效或沒有傳遞,就會報401錯誤。
相關(guān)處理
1. 第1種情況,可以在axios請求攔截器中做token傳遞操作。
2. 第2種情況,之前是這樣處理的,在axios響應(yīng)攔截器中判斷請求狀態(tài)如果是401,就強(qiáng)制用戶重新登錄系統(tǒng)
這樣處理用戶體驗(yàn)非常不好,現(xiàn)在做一次升級優(yōu)化處理。

服務(wù)器端返回兩個秘鑰信息,它們在服務(wù)端都有使用時效:
token有效期2小時。refresh_token有效期14天,refresh_token用于在token過期后,重新獲取并刷新token時效使用的。
針對第2種401狀態(tài)碼處理步驟為:
1. 判斷refresh_token是否存在
不存在就直接重新登錄。
存在,axios發(fā)起請求,帶著refresh_token請求服務(wù)端,獲取新token出來:
成功:對vuex和localStorage進(jìn)行token信息更新。
失?。呵蹇諢o效用戶信息,直接重新登錄。
示例代碼1
// 響應(yīng)攔截器 (響應(yīng)成功:剝離無效數(shù)據(jù),響應(yīng)失?。核⑿聇oken)
instance.interceptors.response.use(res => {
// 將來獲取數(shù)據(jù):res.data.data 麻煩
// 想要結(jié)果:data 即可
try {
return res.data.data
} catch (e) {
return res
}
}, async err => {
try {
// 目的:刷新token
if (err.response && err.response.status === 401) {
// 未登錄 跳轉(zhuǎn)登錄頁面 阻止程序運(yùn)行
const { user } = store.state
// 如果沒有token沒登錄 如果沒有refresh_token無法刷新token
if (!user.token || !user.refresh_token) {
router.push('/login')
return Promise.reject(err)
}
// 刷新token,發(fā)請求,沒有配置的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
})
// 繼續(xù)發(fā)送剛才錯誤的請求
// instance({之前錯誤的請求配置})
// err錯誤對象 包含(response 響應(yīng)對象 |config 請求配置)
return instance(err.config)
}
} catch (e) { // exception 異常
// 刷新token失敗
router.push('/login')
return Promise.reject(e)
}
return Promise.reject(err)
})
演示代碼:promise錯誤處理:

示例代碼2
import store from '@/store' // 引入vuex中的store實(shí)例
import router from '@/router' // 引入路由對象實(shí)例
……
// 響應(yīng)攔截器
instance.interceptors.response.use(
function (response) {
try {
// 返回具體有價值的業(yè)務(wù)數(shù)據(jù)
return response.data.data
} catch (error) {
return response.data
}
},
async function (error) {
// 響應(yīng)有錯誤,有可能錯誤狀態(tài)碼為401
if (error.response && error.response.status === 401) {
// 定義登錄路由對象
let toPath = {
name: 'login',
query: { redirectUrl: router.currentRoute.path }
} // 跳轉(zhuǎn)對象
// 如果refresh_token不存在
if (!store.state.user.refresh_token) {
router.push(toPath)
return Promise.reject(error)
}
try {
// 刷新用戶token
// 應(yīng)該發(fā)送一個請求 換取新的token
// 這里不應(yīng)該再用instance 因?yàn)?instance會再次進(jìn)入攔截器 用默認(rèn)的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進(jìn)行更新
store.commit('updateUser', {
token: result.data.data.token, // 拿到新的token之后
refresh_token: store.state.user.refresh_token // 將之前 refresh_token 14天有效期
})
return instance(error.config) // 把剛才錯誤的請求再次發(fā)送出去 然后將promise返回
} catch (err) {
// 如果錯誤 表示補(bǔ)救措施也沒用了(有可能refresh_token也失效了)
// 應(yīng)該跳轉(zhuǎn)到登錄頁 并且 把廢掉的用戶信息全都干掉
store.commit('clearUser') // 所有的用戶信息清空
router.push(toPath) // 跳轉(zhuǎn)到回登錄頁
return Promise.reject(err)
}
}
return Promise.reject(error)
}
)
') // 所有的用戶信息清空
router.push(toPath) // 跳轉(zhuǎn)到回登錄頁
return Promise.reject(err)
}
}
return Promise.reject(error)
}
)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
MAC系統(tǒng)IDEA顏值插件MaterialThemeUI
俗話說,工欲善其事必先利其器。工具的顏值也很重要,好的主題讓人賞心悅目,有碼代碼的欲望。今天推薦一個IDEA顏值類插件:Material Theme UI2021-09-09
關(guān)于Unity動畫狀態(tài)機(jī)Animator使用教程
這篇文章主要介紹了關(guān)于Unity動畫狀態(tài)機(jī)Animator的使用教程,有需要的朋友可以借鑒參考下,希望可以對廣大讀者朋友能夠有所幫助2021-09-09
git log根據(jù)特定條件查詢?nèi)罩静⒔y(tǒng)計修改的代碼行數(shù)
這篇文章主要介紹了git log根據(jù)特定條件查詢?nèi)罩静⒔y(tǒng)計修改的代碼行數(shù),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-09-09
Postman配置多環(huán)境請求地址的實(shí)現(xiàn)
本文主要介紹了Postman配置多環(huán)境請求地址的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01

