uniapp 实现无感刷新token, 适应大多数项目

不管你是用taro uni 还是vue-cli 或者 react-cli 刷新token这块一通百通 本质上 都一样
我之前讲了一个是 在响应拦截哪里做token刷新 其实这样做还是不好的,因为这样我们发起了请求, 相对来说 还是在请求之前做比较好 那样可以避免 几次请求吧

因为在 axis 中有帮我们处理的拦截器 在uniapp 中也需要我们做一个拦截器
这里直接使用uniapp插件市场找到的一个。 但是其中很多我们可能用不到 我就给删减了很多。

在common下创建一个 http.js
我这里的是最简的版本 什么其他请求和请求日志的都删除了 只留下我用到的

// 拦截器
export default {
    
    
  config: {
    
    
    baseUrl: "", // 请求域名的基础地址
    header: {
    
    
      Accept: "application/json, text/plain, */*",
      "Content-Type": "application/x-www-form-urlencoded",
    },
    data: {
    
    },
    method: "POST", // 默认post请求
    dataType: "json" /* 如设为json,会对返回的数据做一次 JSON.parse */,
    responseType: "text",
    success() {
    
    },
    fail() {
    
    },
    complete() {
    
    },
  },
  interceptor: {
    
    
    request: null,
    response: null,
  },
  request(options) {
    
    
    if (!options) {
    
    
      options = {
    
    };
    }
    options.baseUrl = options.baseUrl || this.config.baseUrl;
    options.dataType = options.dataType || this.config.dataType;
    options.url = options.baseUrl + options.url;
    options.data = options.data || {
    
    };
    options.method = options.method || this.config.method;

    return new Promise((resolve, reject) => {
    
    
      let _config = null;

      options.complete = (response) => {
    
    
        let statusCode = response.statusCode;
        response.config = _config;
        if (this.interceptor.response) {
    
    
          let newResponse = this.interceptor.response(response);
          if (newResponse) {
    
    
            response = newResponse;
          }
        }
        if (statusCode === 200) {
    
    
          //成功
          resolve(response);
        } else {
    
    
          reject(response);
        }
      };

      _config = Object.assign({
    
    }, this.config, options);
      _config.requestId = new Date().getTime();

      if (this.interceptor.request) {
    
    
        this.interceptor.request(_config);
      }
      uni.request(_config);
    });
  },
};

然后就是在我们的 request.js中使用了
这里提一句就是 一般来说 token有一个过期时间。我这里判断的是 在距离过期还有一个小时内。用户操作 就会刷新token重新延长12个小时(这个token存在时间不同的公司规定应该是不一样的哦)

let isRefreshing = false, requestQueue = [] // 重新执行队列
// 请求拦截
  http.interceptor.request = async (config) => {
    
    
  	let _userToken = uni.getStorageSync('token')
  	config.header['token'] = _userToken.token
    //无感刷新处理
    const nowTime = parseInt(new Date().getTime() / 1000); //过期前一个小时
    const expireTime = (_userToken.tokenExpiresTime || 0) > 0 ? parseInt(_userToken.tokenExpiresTime) - 3600 : 0;
    if (token && nowTime > expireTime) {
    
    
      if (!isRefreshing) {
    
     // 一次进入一个刷新token
        isRefreshing = true
        // 刷新token的请求方法 是基于promise 封装的一个请求方法
        // 我放在了 vuex中的actions中
        const res = await store.dispatch({
    
    
          type: 'user/refreshToken',
          token: _userToken.token,
          freshToken: _userToken.freshToken
        })
        uni.setStorageSync('token', res.Data)
        requestQueue.forEach(cb => cb(token));
        isRefreshing = false
        requestQueue = [];  // 清空请求队列
      }

      const request = new Promise(resolve => {
    
    
        requestQueue.push(token => {
    
    
          config.header["token"] = token;
          resolve(config);
        });
      });
      return request;
    }

    return config;
  };

这样用户就不用抱怨 我在登录的时候 一直操作着 莫名其妙就掉线了。哈哈哈

关注我 持续更新前端知识。

还有不懂的地方 可以私信我哦

猜你喜欢

转载自blog.csdn.net/yunchong_zhao/article/details/123404501