Предисловие 🎈
Я столкнулся с проблемой при написании проекта (Vue), истечение срока действия токена, возвращаемого бэкендом. Это очень распространенная проблема на поверхности, но моя проблема относительно невелика 😂
Вопрос❓
Страница внешнего интерфейса может содержать более одной страницы при инициализации страницы.token
Если эти запросы не являются взаимозависимыми, целесообразно обрабатывать параллельный запрос.
Затем возникает проблема, запрос является асинхронным поведением, даже если запрос выполняется одновременно, данные должны быть возвращены последовательно, и первые возвращенные данные подскажут намtoken
Срок действия истек, тогда он вызовет наш пакет функций запроса тамtoken
Обработка истечения срока действия (очистить локальный кешtoken
, и присоединение текущего недействительного адреса к переходу по адресу входа)
пример:
login?callback=xxxxx
Есть несколько запросов, поэтому будет срабатывать несколько перехватов ответов, и время срабатывания будет разным.Возможно даже, что после входа на страницу входа некоторые ответы только что вернулись из фона, а это не то, что мы хотим см., т.к. это вызовет много неизвестных проблем.Ситуация, с которой я сталкиваюсь сейчас, заключается в том, что если первый ответ вернет недействительный токен, я выполню операцию перехвата, чтобы получить URL-адрес текущей недопустимой страницы.order?id=1
Этот адрес, перейти кlogin
страница
//我这边把 order?id=1 base64位加密
let path = "/order?id=1" //vue的路由
path = Base64.encode(path)
let callback=`login?callback=${path}`
Затем, после перехода на страницу входа, будет ответ перед возвратом из бэкэнда, затем эта функция перехвата снова обрабатывает адрес
let path = "/login?callback=xxx" //当前获取到的地址变成了登录页
path = Base64.encode(path)
let callback=`login?callback=${path}`
Вылезла эта проблема 💥
Решение 🔑
первый метод
Одна модификация функции перехвата, которую я используюaxios
axios.interceptors.response.use(response => {
//对于token过期的处理
if (response.data.code == 102) {
let path = location.hash.split("/")[1]
if (!(/callback/g).test(path)) {
let code = Base64.encode(path)
router.replace("/login?callback=" + code)
}
}
})
для переносимости адресовcallback
URL-адрес поля всегда перехватывается, хотя это грубо, но может решить проблему.
Второй способ
Для улучшения первого метода используйтеcallback
В конце концов, поле кажется немного проблематичным.Ознакомьтесь с документацией axios, есть конфигурация блокирующая запросыcancelToken
, затем используйте его для преобразования этой функции перехвата
const cancelToken = axios.CancelToken; //阻止请求
const pendding = [] //把当前请求的状态都存到一个数组里
axios.interceptors.request.use(config => {
config.cancelToken = new cancelToken((c) => {
pendding.push({ fun: c, url: config.url })
})
})
request.interceptors.response.use(response => {
//对于token过期的处理
if(response.data.code===200){
//对于请求ok的数据
for (let i in pendding) {
if(response.config.url===pendding[i].url){
pendding.splice(i, 1); //把这条记录从数组中移除
}
}
return response.data
}
if(response.data.code===102){
for (let i in pendding) {
pendding[i].fun(); //执行取消操作
pendding.splice(i, 1); //把这条记录从数组中移除
}
let path = location.hash.split("/")[1]
let code = Base64.encode(path)
router.replace("/login?callback=" + code)
}
})
В настоящее время логика
- Перехват запроса, создание массива для всех запрашивающих API
- С точки зрения перехвата ответа данные запроса 200 удаляются из массива запросов, а для запросов с просроченными токенами выполняется операция отмены запроса, которая уже инициировала запрос, но не вернула ответ, и удаляется из массива запросов.
Резюме 😊
В этой статье собраны проблемы, с которыми я столкнулся, и текущие решения. Я считаю, что это не лучшее решение, я могу думать только об этих двух способах из-за своих ограниченных возможностей.
Теперь еще есть момент, который можно оптимизировать и модифицировать, то есть запрос возвращается одновременно (интервал очень короткий), из-за чего функция перехвата срабатывает более одного раза. вернутьtoken
После аннулирования последующие запросы не нужно отправлять повторно. В ответ на эту проблему все, что я думаю, это сначала отправить предварительный запрос, а запрос возвращаетtoken
Это нормально, а потом отправлять другие запросы, самый глупый способ, который я могу придумать на данный момент 😥
created: async (){
let result = await verifyToken()
if(result.code===200){
//其余的请求
}
}
Много советов, учитесь друг у друга
Ссылки 📒
В этой статье используетсяmdniceнабор текста