关于前端:使用原生-cookieStore-方法让-Cookie-操作更简单

136次阅读

共计 5401 个字符,预计需要花费 14 分钟才能阅读完成。

前言

对于前端来讲,咱们在操作 cookie 时往往都是基于 document.cookie,但它有一个毛病就是操作简单,它并没有像localStorage 那样提供一些 getset等办法供咱们应用。对与 cookie 的操作一切都是基于字符串来进行的。为了让 cookie 的操作更简便,Chrome87 率先引入了 cookieStore 办法。

document.cookie

document.cookie能够获取并设置以后文档关联的cookie

获取 cookie

const cookie = document.cookie

在下面的代码中,cookie 被赋值为一个字符串,该字符串蕴含所有的 Cookie,每条 cookie 以 ” 分号和空格 (;)” 分隔 (即,key=value 键值对)。

但这拿到的是一整个字符串,如果你想获取 cookie 中的某一个字段,还须要本人解决

const converter = {read: function (value) {if (value[0] === '"') {value = value.slice(1, -1);
    }
    return value.replace(/(%[\dA-F]{2})+/gi, decodeURIComponent)
  },
  write: function (value) {return encodeURIComponent(value).replace(/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,
      decodeURIComponent
    )
  }
}
function getCookie (key) {const cookies = document.cookie ? document.cookie.split(';') : [];
  const jar = {};
  for (let i = 0; i < cookies.length; i++) {const parts = cookies[i].split('=');
    const value = parts.slice(1).join('=');

    try {const foundKey = decodeURIComponent(parts[0]);
      jar[foundKey] = converter.read(value, foundKey);

      if (key === foundKey) {break}
    } catch (e) {}}
  return key ? jar[key] : jar
}
console.log(getCookie('name'))  // 前端南玖

比方下面这段代码就是用来获取单个 cookie 值的

设置 cookie

document.cookie = `name= 前端南玖;`

它的值是一个键值对模式的字符串。须要留神的是,用这个办法一次只能对一个 cookie 进行设置或更新

比方:

document.cookie = `age=18; city=shanghai;`

这样只有 age 可能设置胜利

  • 以下可选的 cookie 属性值能够跟在键值对后,用来具体化对 cookie 的设定 / 更新,应用分号以作分隔:

    • ;path=path (例如 ‘/’, ‘/mydir’) 如果没有定义,默认为以后文档地位的门路。
    • ;domain=domain (例如 ‘example.com’,‘subdomain.example.com’) 如果没有定义,默认为以后文档地位的门路的域名局部。与晚期标准相同的是,在域名后面加 . 符将会被忽视,因为浏览器兴许会回绝设置这样的 cookie。如果指定了一个域,那么子域也蕴含在内。
    • ;max-age=max-age-in-seconds (例如一年为 606024*365)
    • ;expires=date-in-GMTString-format

      如果没有定义,cookie 会在对话完结时过期

      • 这个值的格局参见 Date.toUTCString() (en-US)
    • ;secure (cookie 只通过 https 协定传输)
  • cookie 的值字符串能够用 encodeURIComponent() (en-US)来保障它不蕴含任何逗号、分号或空格 (cookie 值中禁止应用这些值).
function assign (target) {for (var i = 1; i < arguments.length; i++) {var source = arguments[i];
    for (var key in source) {target[key] = source[key];
    }
  }
  return target
}
function setCookie (key, value, attributes) {if (typeof document === 'undefined') {return}

  attributes = assign({}, { path: '/'}, attributes);

  if (typeof attributes.expires === 'number') {attributes.expires = new Date(Date.now() + attributes.expires * 864e5);
  }
  if (attributes.expires) {attributes.expires = attributes.expires.toUTCString();
  }

  key = encodeURIComponent(key)
    .replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent)
    .replace(/[()]/g, escape);

  var stringifiedAttributes = '';
  for (var attributeName in attributes) {if (!attributes[attributeName]) {continue}

    stringifiedAttributes += ';' + attributeName;

    if (attributes[attributeName] === true) {continue}
    stringifiedAttributes += '=' + attributes[attributeName].split(';')[0];
  }

  return (document.cookie =
          key + '=' + converter.write(value, key) + stringifiedAttributes)
}

setCookie('course', 'fe', { expires: 365})

这里是 js-cookie 库对 setCookie 办法的封装

删除 cookie

function removeCookie (key, attributes) {
  setCookie(
    key,
    '',
    assign({}, attributes, {expires: -1})
  );
}

removeCookie('course')

新办法 cookieStore

以上就是通过 document.cookie 来操作 cookie 的办法,未封装办法之前操作起来都十分的不不便。当初咱们再来理解一下新办法 cookieStore,它是一个相似localStorage 的全局对象。

它提供了一些办法能够让咱们更加不便的操作cookie

获取单个 cookie

cookieStore.get(name)

该办法能够获取对应 key 的单个 cookie,并且以 promise 模式返回对应的值

async function getCookie (key) {const name = await cookieStore.get(key)
  console.log('【name】', name)
}
getCookie('name')

当获取的 cookie 不存在时,则会返回null

获取所有 cookie

cookieStore.getAll()

该办法能够获取所有匹配的 cookie,并且以promise 模式返回一个列表

async function getAllCookies () {const cookies = await cookieStore.getAll()
  console.log('【cookies】', cookies)
}
getAllCookies()

cookie 不存在时,则会返回一个空数组

设置 cookie

cookieStore.set()

该办法能够设置 cookie,并且会返回一个 promise 状态,示意是否设置胜利

function setCookie (key, value) {cookieStore.set(key, value).then(res => {console.log('设置胜利')
  }).catch(err => {console.log('设置失败')
  })
}
setCookie('site', 'https://bettersong.github.io/nanjiu/')

如果想要设置更多的属性,比方:过期工夫、门路、域名等,能够传入一个对象

function setCookie (key, value) {
  cookieStore.set({
    name: key,
    value: value,
    path: '/',
    expires: new Date(2024, 2, 1)
  }).then(res => {console.log('设置胜利')
  }).catch(err => {console.log('设置失败')

  })
}
setCookie('site', 'https://bettersong.github.io/nanjiu/')

删除 cookie

cookieStore.delete(name)

该办法能够用来删除指定的 cookie,同样会返回一个 promise 状态,来示意是否删除胜利

function removeCookie (key) {cookieStore.delete(key).then(res => {console.log('删除胜利')
  }).catch(err => {console.log('删除失败')
  })
}
removeCookie('site')

须要留神的是:即便删除一个不存在的 cookie 也会返回删除胜利状态

监听 cookie

cookieStore.addEventListener('change', (event) => {console.log(event)
});

能够通过 change 事件来监听 cookie 的变动,无论是通过 cookieStore 操作的,还是通过 document.cookie 来操作的都可能监听到。

该办法的返回值有两个字段比拟重要,别离是:changedelete,它们都是数组类型。用来寄存扭转和删除的 cookie 信息

监听批改

调用 set 办法时,会触发 change 事件,批改或设置的 cookie 会寄存在 change 数组中

cookieStore.addEventListener('change', (event) => {
  const type = event.changed.length ? 'change' : 'delete';
  const data = (event.changed.length ? event.changed : event.deleted).map((item) => item.name);

  console.log(`【${type}】, cookie:${JSON.stringify(data)}`);
});

function setCookie (key, value) {cookieStore.set(key, value).then(res => {console.log('设置胜利')
  }).catch(err => {console.log('设置失败')
  })
}
setCookie('site', 'https://bettersong.github.io/nanjiu/')

⚠️须要留神的是:

  • 通过 document.cookie 设置或删除 cookie 时,都是会触发 change 事件,不会触发 delete 事件
  • 即便两次设置 cookie 的 namevalue都雷同,也会触发 change 事件

监听删除

调用 delete 办法时,会触发 change 事件,删除的 cookie 会寄存在 delete 数组中

cookieStore.addEventListener('change', (event) => {
  const type = event.changed.length ? 'change' : 'delete';
  const data = (event.changed.length ? event.changed : event.deleted).map((item) => item.name);

  console.log(`【${type}】, cookie:${JSON.stringify(data)}`);
});

function removeCookie (key) {cookieStore.delete(key).then(res => {console.log('删除胜利')
  }).catch(err => {console.log('删除失败')
  })
}
removeCookie('site')

⚠️须要留神的是:

  • 如果删除一个不存在的 cookie,则不会触发 change 事件

兼容性

在应用该办法时须要留神浏览器的兼容性

总结

cookieStore提供的办法比起间接操作 document.cookie 要简便许多,不仅反对增删改查,还反对通过 change 事件来监听 cookie 的变动,然而在应用过程须要留神兼容性问题。

正文完
 0