头图

我们知道,通过 document.cookie 可以获取到当前网站所有可用的 cookie

console.log(document.cookie);
// 'token=eyJ0eXAiOiJKV1QiJ9ftU; username=FEHub; userOutId=362236'
当然,细心的小伙伴肯定知道:如果在 Set-Cookie 时设置了 HttpOnly 属性,那么 document.cookie 是无法获取到这个 cookie 的。

好了,现在已经获取到了 cookie,但是他是一个字符串,那如何获取到对应 key 的值呢?

一般情况下,咱们肯定是在 npm 中找一个成熟的第三方库来实现此功能,比如:js-cookie

但是如果咱们只是想要某个 key 的值,并不需要添加或删除 cookie 呢?

在这种场景下,咱们就可以自己手动实现此功能,来减少第三方依赖和打包后的体积。

实现思路

字符串分割

按照 MDN 上面的定义,通过 document.cookie 获取到是通过 ; (分号和空格)连接的 key=value 字符串。

所以,咱们直接通过字符串的 split 方法分割 2 次,即可格式化好所有的 cookie

// console.log(document.cookie); 
// 'token=eyJ0eXAiOiJKV1QiJ9ftU; username=FEHub; userOutId=362236'

const cookieMap = new Map();

document.cookie.split("; ").forEach((cookie) => {
    const [key, value] = cookie.split("=");
    cookieMap.set(key, value);
})

console.log(cookieMap.size);
// 3

console.log(cookieMap.get("username"));
// FEHub

正则匹配

字符串的 match 方法可以传入一个正则表达式用来匹配内容。

如果我们要获取 username 的值,那么可以这样写:

// console.log(document.cookie); 
// 'token=eyJ0eXAiOiJKV1QiJ9ftU; username=FEHub; userOutId=362236'

// 匹配一个存在的值
const result = document.cookie.match(/username=(\w+)/);
//  ['username=FEHub', 'FEHub', index: 29, input: 'token=eyJ0eXAiOiJKV1QiJ9ftU; username=FEHub; userOutId=362236', groups: undefined]

console.log(result[1]);
// FEHub

// 匹配一个不存在的值
const result2 = document.cookie.match(/xxx=(\w+)/);
//  null

针对上面的正则,做一个简单的解释:

  • \w:表示匹配字母、数字、下划线。
  • +:表示至少匹配一次前面的子表达式。
  • ():表示将匹配到的内容放入分组内。

如果匹配到内容,那么直接通过下标 1 即可获取对应的值。

如果获取不到内容, 那么返回值就是 null

然后咱们稍微封装一下,让他变得更通用一些:

const getCookie = (key) => {
  const { cookie } = document;
  return cookie.match(new RegExp(`${key}=(?<key>\\w+)`))?.groups?.key;
};


// console.log(document.cookie); 
// 'token=eyJ0eXAiOiJKV1QiJ9ftU; username=FEHub; userOutId=362236'

console.log(getCookie('username'));
// FEHub

这里再简单提一嘴:

  • 通过 new RegExp 动态生成正则,这样可以动态指定获取的 key
  • 由于生成正则时传入的是字符串表达式,所以需要将 \w 转义为 \\w
  • (?<Name>x) 是正则的具名捕获组语法,目的是为了可以更明确的取值。

关注我

好了,这就是今天分享的全部内容啦 ~

关注我,每天学一个有趣的小知识 😉

微信扫一扫,关注「FEHub」


asong
122 声望8 粉丝

念念不忘,必有回响。