坏蛋格鲁坏蛋格鲁

【Function】JS 封装 Cookie 操作函数


/**
 * CookieHelper – 浏览器 Cookie 的轻量级封装
 * 提供增删改查、批量操作、JSON 序列化、过期时间计算等常用能力。
 * 所有操作默认作用在当前域 (domain) 与当前路径 (path)。
 */
class CookieHelper {
  /**
   * 构造函数
   * @param {Object} [defaults={}] 全局默认值,会作用于每一次 set 操作
   * @param {string} [defaults.path] 默认路径,如 '/'
   * @param {Date} [defaults.expires] 默认过期时间
   * @param {number} [defaults.days] 默认存活天数(与 expires 二选一)
   * @param {string} [defaults.domain] 默认作用域
   * @param {boolean} [defaults.secure=false] 是否仅 HTTPS
   * @param {'Strict'|'Lax'|'None'} [defaults.sameSite] 同站策略
   */
  constructor(defaults = {}) {
    this.defaults = { path: '/', ...defaults };
  }

  /**
   * 设置一条 Cookie
   * @param {string} key 键名
   * @param {*} value 任意可 JSON 序列化的值;普通字符串亦可
   * @param {Object} [options={}] 单次配置,优先级高于构造函数默认值
   * @returns {CookieHelper} 支持链式调用
   */
  set(key, value, options = {}) {
    const opts = { ...this.defaults, ...options };
    let val = typeof value === 'object' ? JSON.stringify(value) : String(value);

    let cookie = `${encodeURIComponent(key)}=${encodeURIComponent(val)}`;

    if (opts.expires instanceof Date) {
      cookie += `; expires=${opts.expires.toUTCString()}`;
    } else if (typeof opts.days === 'number') {
      const date = new Date(Date.now() + opts.days * 864e5);
      cookie += `; expires=${date.toUTCString()}`;
    }

    if (opts.path) cookie += `; path=${opts.path}`;
    if (opts.domain) cookie += `; domain=${opts.domain}`;
    if (opts.secure) cookie += '; secure';
    if (opts.sameSite) cookie += `; samesite=${opts.sameSite}`;

    document.cookie = cookie;
    return this;
  }

  /**
   * 读取一条 Cookie
   * @param {string} key 键名
   * @param {*} [defaultValue=null] 不存在时返回的默认值
   * @returns {*} 解析后的值;若无法解析 JSON 则原样返回字符串
   */
  get(key, defaultValue = null) {
    const name = encodeURIComponent(key) + '=';
    const cookies = document.cookie.split(';');

    for (let c of cookies) {
      c = c.trim();
      if (c.startsWith(name)) {
        try {
          const val = decodeURIComponent(c.substring(name.length));
          return JSON.parse(val);
        } catch {
          return decodeURIComponent(c.substring(name.length));
        }
      }
    }
    return defaultValue;
  }

  /**
   * 删除一条 Cookie(通过设置过期时间为过去的时间)
   * @param {string} key 键名
   * @param {Object} [opts={}] 仅 path / domain 需与当初写入保持一致才能成功删除
   * @returns {CookieHelper} 支持链式调用
   */
  remove(key, opts = {}) {
    opts = { ...this.defaults, ...opts, days: -1 };
    this.set(key, '', opts);
    return this;
  }

  /**
   * 批量设置 Cookie
   * @param {Object} map 键值对对象
   * @param {Object} [opts={}] 公共配置
   * @returns {CookieHelper} 支持链式调用
   */
  setAll(map, opts = {}) {
    Object.entries(map).forEach(([k, v]) => this.set(k, v, opts));
    return this;
  }

  /**
   * 批量获取 Cookie
   * @param {string[]} [keys] 需要获取的键名数组;留空则返回所有 Cookie
   * @returns {Object} 键值对对象
   */
  getAll(keys) {
    const all = {};
    const cookies = document.cookie.split(';');
    for (let c of cookies) {
      const [k, ...v] = c.trim().split('=');
      if (!k) continue;
      const key = decodeURIComponent(k);
      if (keys && !keys.includes(key)) continue;
      try {
        all[key] = JSON.parse(decodeURIComponent(v.join('=')));
      } catch {
        all[key] = decodeURIComponent(v.join('='));
      }
    }
    return keys ? Object.fromEntries(keys.map(k => [k, all[k]])) : all;
  }

  /**
   * 清空当前域下所有可访问的 Cookie
   * @returns {CookieHelper} 支持链式调用
   */
  clear() {
    const all = this.getAll();
    Object.keys(all).forEach(k => this.remove(k));
    return this;
  }
}


// Test
const cookie = new CookieHelper({ secure: true, sameSite: 'Lax' });
cookie.set('theme', 'dark');
cookie.set('age', 56);
cookie.set('user', { id: 123, name: 'Alice' }, { days: 7 });

console.log(cookie.get('user')); // { id: 123, name: 'Alice' }
console.log(cookie.getAll(['theme', 'age']))

cookie.clear();
console.log(cookie.get('theme'));
本原创文章未经允许不得转载 | 当前页面:坏蛋格鲁 » 【Function】JS 封装 Cookie 操作函数

评论