微信小程序打夯之旅(二):Cookie模拟

众所可能周知,微信小程序是不支持 cookie 的,这就很是影响先后端的沟通,因此不得不本身实现一套 cookie 机制了。javascript

使用方式

import cookie from '../plugins/cookie.js';

cookie.getAllString() // 获取cookie字符串
cookie.get('key') // 获取某个cookie值
cookie.set('key', 'value')  // 设置一个新的cookie值
cookie.delete('key')  //删除某个cookie值
cookie.clear()  // 清空cookie

// 在http请求头部的使用:设置请求中的cookie值
opt.header = Object.assign(opt.header || {}, {
  Cookie: cookieUtil.getAllString(),
});

// 在http请求回调的使用:设置回调中的cookie值
const setCookieStr = res.header['Set-Cookie'] || res.header['set-cookie'];
setCookieStr && cookie.parseSetCookie(setCookieStr);
复制代码

原理解读 - cookie.js

/** * 利用 storage 模拟 cookie 操做 * 请求等状况下数据要求较高,因此须要同步操做 * cookie 存储格式:{ key: { value: 'value', expires: 1526452752000 } } */

const storageKey = 'reqCookie';

const Fn = {
  // 获取 cookie 字符串
  getAllString() {
    const cookie = this._getAll();
    const deleteArr = [];
    const result = [];
    Object.keys(cookie).forEach(key => {
      if (typeof cookie[key] !== 'object' || this._checkExpires(cookie[key]) || !cookie[key].value) {
        deleteArr.push(key);
      } else {
        result.push(`${key}=${cookie[key].value}`);
      }
    });
    this.batchDelete(deleteArr);
    return result.join('; ');
  },

  // 获取 cookie 中一个字段
  get(key) {
    if (!key) return;

    const cookie = this._getAll();
    if (this._checkExpires(cookie[key]) || typeof cookie[key] !== 'object') {
      this.delete(key);
    }
    return cookie[key] && cookie[key].value;
  },

  // 设置 cookie 中一个字段
  set(key, value) {
    if (!key) return false;

    try {
      const cookie = this._getAll();
      cookie[key] = typeof value === 'object' ? value : { value };
      wx.setStorageSync(storageKey, JSON.stringify(cookie));
      return true;
    } catch (e) {
      console.error(e);  // eslint-disable-line
      return false;
    }
  },

  // 设置 cookie 多个字段
  batchSet(obj) {
    if (!obj || typeof obj !== 'object') return false;

    try {
      const cookie = this._getAll();
      Object.keys(obj).forEach(key => {
        obj[key] = typeof obj[key] === 'object' ? obj[key] : { value: obj[key] };
      });
      Object.assign(cookie, obj);
      wx.setStorageSync(storageKey, JSON.stringify(cookie));
      return true;
    } catch (e) {
      console.error(e);  // eslint-disable-line
      return false;
    }
  },

  // 删除 cookie 中一个字段
  delete(key) {
    if (!key) return false;

    try {
      const cookie = this._getAll();
      cookie[key] && (delete cookie[key]);  // eslint-disable-line
      wx.setStorageSync(storageKey, JSON.stringify(cookie));
      return true;
    } catch (e) {
      console.error(e);  // eslint-disable-line
      return false;
    }
  },

  // 删除 cookie 多个字段
  batchDelete(keyArr) {
    if (!keyArr || !keyArr.length) return false;

    try {
      const cookie = this._getAll();
      keyArr.forEach(key => {
        cookie[key] && (delete cookie[key]);  // eslint-disable-line
      });
      wx.setStorageSync(storageKey, JSON.stringify(cookie));
      return true;
    } catch (e) {
      console.error(e);  // eslint-disable-line
      return false;
    }
  },

  // 清除 cookie
  clear() {
    try {
      wx.setStorageSync(storageKey, '{}');
      return true;
    } catch (e) {
      console.error(e);  // eslint-disable-line
      return false;
    }
  },

  // 解析 set-cookie
  parseSetCookie(str) {
    if (!str) return;

    const expiresReg = /expires=([^;]+);/gi;
    const setCookieStr = str.replace(expiresReg, (match, time) => `expires=${new Date(time).getTime()};`).replace(/\s+/gi, '');
    const cookieObj = {};
    setCookieStr.split(',').forEach(cookieStr => {
      let key;
      cookieStr.split(';').forEach((part, index) => {
        try {
          const cArr = part.split('=');
          if (index === 0) {
            key = cArr[0];
            cookieObj[key] = { value: cArr[1] };
          } else if (cArr[0] === 'expires') {
            cookieObj[key].expires = cArr[1];
          }
        } catch (e) {
          console.error(e);  // eslint-disable-line
        }
      });
    });
    this.batchSet(cookieObj);
  },

  // 检查 cookie 是否过时
  _checkExpires(valueObj) {
    return valueObj && valueObj.expires && Date.now() > valueObj.expires;
  },

  // 获取 cookie 对象
  _getAll() {
    let cookie = {};
    try {
      const storage = wx.getStorageSync(storageKey);
      cookie = storage ? JSON.parse(storage) : {};
    } catch (e) {
      console.error(e);  // eslint-disable-line
    }
    return cookie;
  },
};

export default Fn;

复制代码
相关文章
相关标签/搜索