微信小程序打夯之旅(二):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;

複製代碼
相關文章
相關標籤/搜索