最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

js無痛刷新Token的實現(xiàn)

 更新時間:2022年03月18日 11:17:37   作者:沐夕花開  
本文主要介紹了js無痛刷新Token的實現(xiàn),文中根據(jù)實例編碼詳細介紹的十分詳盡,具有一定的參考價值,感興趣的小伙伴們可以參考一下

這個需求場景很常見,幾乎很多項目都會用上,之前項目也實現(xiàn)過,最近剛好有個項目要實現(xiàn),重新梳理一番。

需求

對于需要前端實現(xiàn)無痛刷新Token,無非就兩種:

  • 請求前判斷Token是否過期,過期則刷新
  • 請求后根據(jù)返回狀態(tài)判斷是否過期,過期則刷新

處理邏輯

實現(xiàn)起來也沒多大差別,只是判斷的位置不一樣,核心原理都一樣:

  • 判斷Token是否過期

    沒過期則正常處理

    過期則發(fā)起刷新Token的請求

    拿到新的Token保存

    重新發(fā)送Token過期這段時間內發(fā)起的請求

重點:

  • 保持Token過期這段時間發(fā)起請求狀態(tài)(不能進入失敗回調)
  • 把刷新Token后重新發(fā)送請求的響應數(shù)據(jù)返回到對應的調用者

實現(xiàn)

  • 創(chuàng)建一個flag isRefreshing 來判斷是否刷新中
  • 創(chuàng)建一個數(shù)組隊列retryRequests來保存需要重新發(fā)起的請求
  • 判斷到Token過期isRefreshing = false 的情況下 發(fā)起刷新Token的請求

    刷新Token后遍歷執(zhí)行隊列retryRequests

    isRefreshing = true 表示正在刷新Token,返回一個Pending狀態(tài)的Promise,并把請求信息保存到隊列retryRequests

import axios from "axios";
import Store from "@/store";
import Router from "@/router";
import { Message } from "element-ui";
import UserUtil from "@/utils/user";

// 創(chuàng)建實例
const Instance = axios.create();
Instance.defaults.baseURL = "/api";
Instance.defaults.headers.post["Content-Type"] = "application/json";
Instance.defaults.headers.post["Accept"] = "application/json";

// 定義一個flag 判斷是否刷新Token中
let isRefreshing = false;
// 保存需要重新發(fā)起請求的隊列
let retryRequests = [];

// 請求攔截
Instance.interceptors.request.use(async function(config) {
  Store.commit("startLoading");
  const userInfo = UserUtil.getLocalInfo();
  if (userInfo) {
    //業(yè)務需要把Token信息放在 params 里面,一般來說都是放在 headers里面
    config.params = Object.assign(config.params ? config.params : {}, {
      appkey: userInfo.AppKey,
      token: userInfo.Token
    });
  }
  return config;
});

// 響應攔截
Instance.interceptors.response.use(
  async function(response) {
    Store.commit("finishLoading");
    const res = response.data;
    if (res.errcode == 0) {
      return Promise.resolve(res);
    } else if (
      res.errcode == 30001 ||
      res.errcode == 40001 ||
      res.errcode == 42001 ||
      res.errcode == 40014
    ) {
    // 需要刷新Token 的狀態(tài) 30001 40001 42001 40014
    // 拿到本次請求的配置
      let config = response.config;
    //   進入登錄頁面的不做刷新Token 處理
      if (Router.currentRoute.path !== "/login") {
        if (!isRefreshing) {
            // 改變flag狀態(tài),表示正在刷新Token中
          isRefreshing = true;
        //   刷新Token
          return Store.dispatch("user/relogin")
            .then(res => {
            // 設置刷新后的Token
              config.params.token = res.Token;
              config.params.appkey = res.AppKey;
            //   遍歷執(zhí)行需要重新發(fā)起請求的隊列
              retryRequests.forEach(cb => cb(res));
            //   清空隊列
              retryRequests = [];
              return Instance.request(config);
            })
            .catch(() => {
              retryRequests = [];
              Message.error("自動登錄失敗,請重新登錄");
                const code = Store.state.user.info.CustomerCode || "";
                // 刷新Token 失敗 清空緩存的用戶信息 并調整到登錄頁面
                Store.dispatch("user/logout");
                Router.replace({
                  path: "/login",
                  query: { redirect: Router.currentRoute.fullPath, code: code }
                });
            })
            .finally(() => {
                // 請求完成后重置flag
              isRefreshing = false;
            });
        } else {
          // 正在刷新token,返回一個未執(zhí)行resolve的promise
          // 把promise 的resolve 保存到隊列的回調里面,等待刷新Token后調用
          // 原調用者會處于等待狀態(tài)直到 隊列重新發(fā)起請求,再把響應返回,以達到用戶無感知的目的(無痛刷新)
          return new Promise(resolve => {
            // 將resolve放進隊列,用一個函數(shù)形式來保存,等token刷新后直接執(zhí)行
            retryRequests.push(info => {
                // 將新的Token重新賦值
              config.params.token = info.Token;
              config.params.appkey = info.AppKey;
              resolve(Instance.request(config));
            });
          });
        }
      }
      return new Promise(() => {});
    } else {
      return Promise.reject(res);
    }
  },
  function(error) {
    let err = {};
    if (error.response) {
      err.errcode = error.response.status;
      err.errmsg = error.response.statusText;
    } else {
      err.errcode = -1;
      err.errmsg = error.message;
    }
    Store.commit("finishLoading");
    return Promise.reject(err);
  }
);

export default Instance;

到此這篇關于js無痛刷新Token的實現(xiàn)的文章就介紹到這了,更多相關js無痛刷新Token內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 給超鏈接添加特效鼠標移動展示提示信息且隨鼠標移動

    給超鏈接添加特效鼠標移動展示提示信息且隨鼠標移動

    需要實現(xiàn)這樣的效果,就是給超鏈接添加特效當鼠標移動到上展示提示信息且提示信息跟隨鼠標移動,經(jīng)測試還不錯,感興趣的朋友可以參考下
    2013-10-10
  • JavaScript實現(xiàn)私有屬性的幾種方式小結

    JavaScript實現(xiàn)私有屬性的幾種方式小結

    在JavaScript中,私有屬性是指只能在對象內部訪問的屬性,外部無法直接訪問,JavaScript并沒有提供官方的私有屬性的支持,但可以通過一些技巧來模擬實現(xiàn)私有屬性,所以本文給大家總結了JavaScript實現(xiàn)私有屬性的幾種方式,需要的朋友可以參考下
    2024-04-04
  • JavaScript鼠標特效大全

    JavaScript鼠標特效大全

    這篇文章主要為大家詳細介紹了JavaScript鼠標特效,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • JS分別利用分頁加載和懶加載預覽PDF

    JS分別利用分頁加載和懶加載預覽PDF

    在開發(fā)過程中,我們經(jīng)常會遇到預覽PDF的需求,這篇文章主要為大家詳細介紹了JS如何利用分頁加載和懶加載預覽PDF,希望對大家有所幫助
    2024-01-01
  • JS 學習筆記 防止發(fā)生命名沖突

    JS 學習筆記 防止發(fā)生命名沖突

    為了防止發(fā)生命名沖突,可以建立自己的代碼庫。
    2009-07-07
  • layer彈出層倒計時關閉的實現(xiàn)方法

    layer彈出層倒計時關閉的實現(xiàn)方法

    今天小編就為大家分享一篇layer彈出層倒計時關閉的實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-09-09
  • javascript面向對象之訪問對象屬性的兩種方式分析

    javascript面向對象之訪問對象屬性的兩種方式分析

    這篇文章主要介紹了javascript面向對象之訪問對象屬性的兩種方式分析,實例分析了直接訪問對象屬性的方式與數(shù)組訪問方式,需要的朋友可以參考下
    2015-01-01
  • JavaScript Promise原理與實現(xiàn)刨析

    JavaScript Promise原理與實現(xiàn)刨析

    首先呢,Promise是異步中比較重要的知識點,學習的最好方法就是掌握它的基本原理。所以這一篇主要說一下如何用JS來實現(xiàn)一個自己的promise
    2022-10-10
  • JS鮮為人知的問題之[] == ![]結果為true、而{} == !{}卻為false

    JS鮮為人知的問題之[] == ![]結果為true、而{} == !{}卻為false

    這篇文章主要給大家介紹了關于JS鮮為人知的問題之[] == ![]結果為true、而{} == !{}卻為false的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-05-05
  • js實現(xiàn)文本框支持加減運算的方法

    js實現(xiàn)文本框支持加減運算的方法

    這篇文章主要介紹了js實現(xiàn)文本框支持加減運算的方法,可實現(xiàn)文本框輸入加減運算式同時右側實時顯示對應計算結果的功能,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-08-08

最新評論

福贡县| 彰化县| 彰武县| 永新县| 道真| 定襄县| 通榆县| 稷山县| 承德市| 金湖县| 藁城市| 囊谦县| 揭西县| 泰顺县| 邯郸县| 南岸区| 桦甸市| 丁青县| 松原市| 克拉玛依市| 小金县| 肇州县| 景洪市| 宝山区| 腾冲县| 大石桥市| 太保市| 宜春市| 扶风县| 浮梁县| 长武县| 海盐县| 紫金县| 桃园县| 灵璧县| 平武县| 深水埗区| 瑞金市| 丽江市| 轮台县| 四子王旗|