我们知道,通过 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}=(?\\w+)`))?.groups?.key;
};
// console.log(document.cookie);
// 'token=eyJ0eXAiOiJKV1QiJ9ftU; username=FEHub; userOutId=362236'
console.log(getCookie('username'));
// FEHub
这里再简单提一嘴:
- 通过
new RegExp
动态生成正则,这样可以动态指定获取的key
。 - 由于生成正则时传入的是字符串表达式,所以需要将
\w
转义为\\w
。 (?
是正则的具名捕获组语法,目的是为了可以更明确的取值。x)
关注我
好了,这就是今天分享的全部内容啦 ~
关注我,每天学一个有趣的小知识