vue接口数据缓存,防止频繁访问接口

注:本篇博客借鉴了https://segmentfault.com/a/1190000022758406
在此基础上,又根据我的项目https://blog.csdn.net/fmtzy1991/article/details/109065167
做了部分改变;

  1. 目录结构
    在这里插入图片描述
  2. 用到了apiBefor,cryptoHelper,storage三个文件
  3. apiBefor 是对接口的再封装
    import axios from 'axios';
    import storage from './storage';
    import cryptoHelper from './cryptoHelper';
    
    const root = process.env.API_ROOT;
    
    if (process.env.NODE_ENV === "development") {
      axios.defaults.baseURL = root
    }else {
      axios.defaults.baseURL = root
    }
    axios.defaults.headers.post['Content-Type']='application/x-www-form-urlencoded';
    
    const CANCELTTYPE = {
      CACHE: 1,
      REPEAT: 2,
    };
    
    const pendingRequests = [];
    
    const http = axios.create();
    
    http.interceptors.request.use((config) => {
      /**
       * 为每一次请求生成一个cancleToken
       */
      const source = axios.CancelToken.source();
      config.cancelToken = source.token;
      /**
       * 缓存命中判断
       * 成功则取消当次请求
       */
      //处理FormData生成详细key存储数据
      let objData = {};
      for (let entry of config.data.entries()){
        objData[entry[0]] = entry[1];
      }
      //尝试获取缓存数据
      const data = storage.get(cryptoHelper.encrypt(
        config.url + JSON.stringify(objData) + (config.method || '')
      ));
      if (data && (Date.now() <= data.exppries)) {
        console.log(`接口:${config.url} 参数:${JSON.stringify(objData)}缓存命中 -- ${Date.now()} -- ${data.exppries}`);
        source.cancel(JSON.stringify({
          type: CANCELTTYPE.CACHE,
          data: data.data,
        }));
      }
      return config;
    });
    
    http.interceptors.response.use((res) => {
      if (res.data) {
        const dataParse = res.data;
        //添加缓存时间
        if (!dataParse.cacheTime) {
          dataParse.cacheTime = 1000 * 60 * 5;
        }
        //处理FormData生成详细key存储数据
        let objData = {};
          for (let entry of res.config.data.entries()){
            objData[entry[0]] = entry[1];
          }
          //设置缓存数据
          storage.set(cryptoHelper.encrypt(res.config.url + JSON.stringify(objData) + (res.config.method || '')), {
              data: res.data,
              exppries: Date.now() + dataParse.cacheTime,
            });
          console.log(`接口:${res.config.url} 参数:${JSON.stringify(objData)} 设置缓存,缓存时间: ${dataParse.cacheTime}`);
        return res.data;
      } else if(res.data == ''){
        return res.data;
      }else {
        return Promise.reject('接口报错了!');
      }
    });
    
    /**
     * 封装 get、post 请求
     * 集成接口缓存过期机制
     * 缓存过期将重新请求获取最新数据,并更新缓存
     * 数据存储在localstorage
     * {
     *      cache: true
     *      cacheTime: 1000 * 60 * 3  -- 默认缓存3分钟
     * }
     */
    const httpHelper = {
      get(url, params) {
        return new Promise((resolve, reject) => {
          http.get(url, params).then(async (res) => {
            resolve(res);
          }).catch(error => {
            if (axios.isCancel(error)) {
              const cancle = JSON.parse(error.message);
              if (cancle.type === CANCELTTYPE.REPEAT) {
                return resolve([]);
              } else {
                return resolve(cancle.data);
              }
            } else {
              return reject(error);
            }
          });
        });
      },
      post(url, params) {
        return new Promise((resolve, reject) => {
          http.post(url, params).then(async (res) => {
            resolve(res);
          }).catch(error => {
            if (axios.isCancel(error)) {
              const cancle = JSON.parse(error.message);
              if (cancle.type === CANCELTTYPE.REPEAT) {
                return resolve(null);
              } else {
                return resolve(cancle.data);
              }
            } else {
              return reject(error);
            }
          });
        });
      },
    };
    
    export default httpHelper;
    
    
  4. storage是数据存储
    const Storage = {
       get(key) {
        if (!key) { return; }
        const text = localStorage.getItem(key);
        if (text) {
          return JSON.parse(text);
        } else {
          localStorage.removeItem(key);
          return null;
        }
      },
       set(key, data) {
        if (!key) {
          return;
        }
        localStorage.setItem(key, JSON.stringify(data));
      },
       remove(key) {
        if (!key) {
          return;
        }
        localStorage.removeItem(key);
      }
    }
    
    export default Storage;
    
    
  5. cryptoHelper生成加密串
    import cryptoJs from 'crypto-js';
    
    const CryptoHelper = {
      constructor(key) {
        /**
         * 如需秘钥,可以在实例化时传入
         */
        this.key = key;
      },
      /**
       * 加密
       * @param word
       */
        encrypt(word) {
        if (!word) {
          return '';
        }
        const encrypted = cryptoJs.MD5(word);
        return encrypted.toString();
      }
    }
    
    export default CryptoHelper;
    
    
  6. 注意地方:因为我之前是用fromdata方式传参,所以在生成存储变量时要做一下数据处理,将参数转化为字符串,否则在调取缓存数据时不能精准调取;然后返回数据量过多的接口也不建议使用缓存;
  • 0
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值