js 原生方法操作 cookie 详解

客户端存储小型数据的方式有 ​​cookie​​​ 和 ​​storage​​​ 两种
这两种存储方式都是基于站点的,也就是说不同的站点有不同的​​​cookie​​​和​​storage​

cookie
是 ​​​document​​​ 的属性,也就是 ​​window.document.cookie​​​ 用于存储小的数据,如 ​​username​​ ​​email​​ ​​uuid​​ ​​token​​等,并可以设置数据的过期时间

storage
是 ​​​window​​​ 的属性,也就是 ​​window.localStorage​​ 可以永久存储数据,并可以用于存储相对大一些的数据,一般认为可以存储几M大小的数据

本文介绍 cookie 的常用方法

cookie 是个什么东西

cookie 本质其实就是个字符串,比如,看一下 https://so.com 的 cookie 是这样的

js 原生方法操作 cookie 详解_键值对

也可以通过浏览器调试窗口查看,如 chrome 去 application-> cookie 中查看

js 原生方法操作 cookie 详解_javascript_02

原生 cookie 使用

既然上面看到 ​​cookie​​​ 其实是个字符串,就可以写个读取价值对的方法,在用的时候直接返回键值对。更简单的,可以直接使用 ​​jquery.cookie.js​​ 对应的使用方法可以百度,这里不再细说。

这里说一下比较细节的地方,关于设置 cookie 时的一些参数:

参数名

说明

例子

可选参数

path

默认是当前文档的目录

​/​

domain

cookie 作用域名,不同域名会有不同的 cookie

​kylebing.cn​

max-age

秒为单位,最大存活时长

60

expires

存活截止时间。Date.toUTCString() 形式的时间格式。 如果 max-age 和 expires 都没有设置,这个 cookie 就是 session 类型的,关闭当前窗口就删掉了

Mon, 16 Dec 2019 01:45:15 GMT

secure

通过 https 传输

samesite

这块还不太了解

​strict​​​、​​lax​

设置 cookie

原生设置 cookie 是这样的

document.cookie ='新 cookie 字符串'
document.cookie = "name=Kyle;path=/;domain=kylebing.cn;max-age=60;secure=https;samesite=strict"

js 原生方法操作 cookie 详解_js_03

读取 cookie

1. 读取 cookie 字符串

读取 cookie,是直接把整个 cookie 字段拿到,再拆开字符串

let cookieString = document.cookie

// diaryEmail=kylebing%40163.com; diaryUsername=%E5%8D%81%E6%9C%88; diaryUid=3; diaryCategories=%5B%22life%22%2C%22study%22%2C%22work%22%2C%22sport%22%2C%22game%22%2C%22film%22%2C%22bigevent%22%2C%22other%22%5D; diaryToken=123456789123456789;

2. 拆分键值字符串

先观察这个字符串的规律,每个键值对是以 ​​;​​​ 分隔的,名字和值之间以 ​​=​​​ 分隔。
这些键值对之间除了 ​​​;​​​ 之外还有一个空格,只有最后一个是单独的 ​​;​

所以我们要做的就是先把最后面的 ​​;​​ 去掉,然后再拆分整个字符串

let cookie = 'diaryEmail=kylebing%40163.com; diaryUsername=%E5%8D%81%E6%9C%88; diaryUid=3; diaryCategories=%5B%22life%22%2C%22study%22%2C%22work%22%2C%22sport%22%2C%22game%22%2C%22film%22%2C%22bigevent%22%2C%22other%22%5D; diaryToken=123456789123456789;';
cookie = cookie.substring(0, cookie.length - 1); // 去掉最后的 `;` 号
let tempCookieArray =  cookie.split('; '); // 拆分字符串

js 原生方法操作 cookie 详解_键值对_04

3. 分离出字符串中的键和值

遍历前面拆分开的字符串,取 ​​=​​ 前后的内容,前面是名,后面是值

tempCookieArray.forEach(item => {
let name = item.substring(0, item.indexOf('='));
let value = item.substring(item.indexOf('=') + 1);
console.log(`${name}: ${value}`);
});

输出如下:

js 原生方法操作 cookie 详解_cookie_05

4. 转义字符串

此时发现一个问题,就是值里如果有汉字什么的,它显示的是被处理的字符串,我们需要把它还原回来。

这里先做一个测试,我们可以通过 ​​decodeURIComponent()​​ 这个方法还原字符串

这个方法相对的方法是下面这个,看名字就知道什么意思了,目的是转成可以在地址栏中显示的字符

  • encodeURIComponent()
  • decodeURIComponent()

js 原生方法操作 cookie 详解_cookie_06

有了以上的知识,我们就可以还原 ​​cookie​​ 中的内容了

value = decodeURIComponent(value)

5. 放入对象中

取得键名和值之后,我们需要把这两个值封装成对象,好在后面用的时候方便。

let cookieObject = {}; // 存放 cookie 键值对

tempCookieArray.forEach(item => {
let name = item.substring(0, item.indexOf('='));
let value = item.substring(item.indexOf('=') + 1);
value = decodeURIComponent(value); // 还原字符串
cookieObject[name] = value; // 将键值插入中这个对象中
});

console.log(cookieObject);

结果如下:

js 原生方法操作 cookie 详解_字符串_07

6. 封装成方法

为了以后方便使用,可以直接封装成方法

/**
* 获取 cookie 对象
* @returns cookie 键值对对象
*/
function getCookieObject() {
let cookieString = document.cookie;
cookieString = cookieString.substring(0, cookieString.length - 1);
let tempCookieArray = cookieString.split('; ');

let cookieObject = {}; // 存放 cookie 键值对

tempCookieArray.forEach(item => {
let name = item.substring(0, item.indexOf('='));
let value = item.substring(item.indexOf('=') + 1);
value = decodeURIComponent(value); // 还原字符串
cookieObject[name] = value; // 将键值插入中这个对象中
});

return cookieObject // 返回包含 cookie 键值对的对象
}

js 原生方法操作 cookie 详解_键值对_08