我们平时对 cookie 的增删改查等操作,都是在操作 document.cookie,这里我们介绍一个新方法cookieStore

1. 平时如何操作 cookie

document.cookie 能获取到当前域所有的 cookie 字符串。每个 cookie 用分号进行隔开:

document.cookie; // "a=1; b=2; c=wenzi"

操作 cookie,均是在操作 document.cookie。如下面就是我常用的一段代码:

/**
* 写cookies
* @param {string} name 写cookie的key
* @param {string|number} value 写cookie的值
* @param {number} day 存储的时间,默认30天
*/
export const setCookie = (name: string, value: string | number, day = 30): void => {
const exp = new Date();
exp.setTime(exp.getTime() + day * 24 * 60 * 60 * 1000);
document.cookie = `${name}=${escape(value.toString())};path=/;expires=${exp.toUTCString()}`;
}; /**
* 读取cookies
* @param {string} name 要获取的cookie名称
* @param {number|boolean} type 是否直接获取对应的值,若存入真值,则直接返回,否则进行解码
*/
export const getCookie = (name: string): string | null => {
const reg = new RegExp(`(^| )${name}=([^;]*)(;|$)`);
const arr = document.cookie.match(reg);
if (arr) {
return unescape(arr[2]);
}
return null;
}; /**
* 删除cookie
* @param name 删除的cookie名称
*/
export const delCookie = (name: string) => {
if (!name) return;
const ex: Date = new Date();
ex.setTime(ex.getTime() - 1);
document.cookie = `${name}=; expires=${ex.toUTCString()};path=/`;
};

可以看到设置、获取和删除 cookie,都是在 document.cookie 上进行操作的。

2. 新方式 cookieStore

现在 Chrome 有了更方便操作 cookie 的方法了cookieStore,这个方法是在 Chrome87 版本加入的,兼容性还不太好。

下图是当前日期 2021/03/15 的兼容性概览,可以发现仅仅是 Chrome 体系支持了 cookieStore。

不过我们可以先来了解它的用法。

cookieStore 现在只能在https 协议下的域名才能访问的到;其他 http 协议的域名里会提示 cookieStore 为 undefined,或者设置失败。

2.1 基本方法

cookieStore 是一个类似localStorage的 object 类型变量。

可以看到 cookieStore 主要有 5 个方法:

  • set: 设置 cookie,可以是 set(name, value),也可以是 set({name, value});
  • get: 获取 cookie,可以是 get(name),或者 get({name});
  • getAll: 获取所有的 cookie;
  • delete: 删除 cookie;
  • onchange: 监听 cookie 的变化;

前 4 个方法天然支持 Promise。接下来我们一个个来了解下。

2.2 设置 cookie

cookieStore.set 方法可以设置 cookie,并返回一个 Promise 状态,表示是否设置成功。

cookieStore
.set('username', 'wenzi')
.then(() => console.log('设置username成功'))
.catch(() => console.error('设置username失败'));

如果我们想要设置更多的属性,例如过期时间,可以传入一个 Object 类型:

cookieStore
.set({
name: 'age',
value: 18,
expires: new Date().getTime() + 24 * 60 * 60 * 1000,
})
.then(() => console.log('设置age成功'))
.catch(() => console.error('设置age失败'));

value 中所有的数据都会默认先执行toString(),然后再进行存储,因此有些非基本类型的数据,最好先转换好。

上面都是我们设置 cookie 成功的情况,那么什么时候会设置失败呢?在本地 localhost 环境会设置失败。

本地 localhost,我们是能获取到cookieStore这个全局变量,也能执行相应的方法,但无法设置成功:

cookieStore.set('username', 'wenzi');

浏览器会发出提示,无法在不安全的域名下通过 CookieStore 中的 set 设置 cookie:

Uncaught (in promise) TypeError: Failed to execute 'set' on 'CookieStore': Cannot modify a secure cookie on insecure origin

添加 catch 后,就能捕获到这个错误:

cookieStore
.set('username', 'wenzi')
.then(() => console.log('设置username成功'))
.catch(() => console.error('设置username失败'));

因此在想使用 cookieStore 时,不能直接通过下面的方式判断,还得新增一个页面 url 的协议来判断:

typeof cookieStore === 'object'; // 判断不准确,本地localhost也会存在

应当使用:

const isSupportCookieStore = typeof cookieStore === 'object' && location.protocol === 'https:'; // 只有在https协议下才使用cookieStore

2.3 获取 cookie

cookieStore.get(name)方法可以获取 name 对应的 cookie,会以 Promise 格式返回所有的属性:

await cookieStore.get('username');

get()方法还可以接收一个 Object 类型,测试后发现,key 的值只能是 name:

await cookieStore.get({ name: 'username' });

当获取的 cookie 不存在时,则返回一个 Promise<null>

2.4 获取所有的 cookie

cookieStore.getAll()方法可以获取当前所有的 cookie,以 Promise<[]>的形式返回的形式返回,数组中的每一项与通过 get()方式获取到的格式一样;若当前域没有 cookie,或者获取不到指定的 cookie,则为空数组;

await cookieStore.getAll();

getAll()方法也可以传入一个 name,用来获取对应的 cookie:

await cookieStore.getAll('username');
await cookieStore.getAll({ name: 'username' });

2.5 删除 cookie

cookieStore.delete(name)用来删除指定的 cookie:

cookieStore
.delete('age')
.then(() => console.log('删除age成功'))
.catch(() => console.error('删除age失败'));

删除成功后则会提示删除成功。

即使删除一个不存在的 cookie,也会提示删除成功。因此,当再次执行上面的代码时,还是会正常提示。

同样的,在 localhost 环境下会提示删除失败。

2.6 监听 cookie 的变化

我们可以通过添加change事件,来监听 cookie 的变化,无论是通过 cookieStore 操作,还是直接操作 document.cookie,都能监听。

添加监听事件:

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)}`);
});

这里面有 2 个重要的字段changed数组和deleted数组,当设置 cookie 时,则 changed 数组里为刚才设置的 cookie;当删除 cookie 时,则 deleted 数组里为刚才删除的 cookie。

2.6.1 设置操作

当调用 set()方法时,会触发 change 事件,同时影响的 cookie 会放在event.changed数组中。

通过 document.cookie 设置或者删除的 cookie,均认为是在修改 cookie,而不是删除。

每次设置 cookie 时,即使两次的 name 和 value 完全一样,也会触发change事件。

cookieStore.set('math', 90);

2.6.2 删除操作

通过 delete()方法删除一个存在的 cookie 时,会触发 change 事件,被删除的 cookie 会放在event.deleted数组中。

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

cookieStore.delete('math');

可以看到,当第二次删除 name 为 math 的 cookie 时,就没有触发 change 事件。

3. 总结

我们整篇了解了下cookieStore的使用和操作,要比我们直接操作 cookie 简便的多,而且还可以通过自身的 change 事件来监听 cookie 的变化。

感谢您关注我的公众号:

一个操作 cookie 的原生方法 cookieStore的更多相关文章

  1. Cookie介绍及JavaScript操作Cookie方法详解

    本文主要为大家简单介绍了以下Cookie的用途.运行机制,以及JavaScript操作Cookie的各种方法,总结的比较全面,希望能给大家带来帮助. 什么是 Cookie “cookie 是存储于访问 ...

  2. 【转载】使用Jquery操作Cookie对象

    Cookies是一种能够让网站服务器把少量数据储存到客户端的硬盘或内存,或是从客户端的硬盘读取数据的一种技术.jQuery是一个封装好的JavaScript库,使用jQuery可以极大地简化了Java ...

  3. Jquery操作Cookie取值错误的解决方法

    使用JQuery操作cookie时 发生取的值不正确,结果发现cookie有四个不同的属性,分享下错误的原因及解决方法. 使用JQuery操作cookie时 发生取的值不正确的问题:  结果发现coo ...

  4. WCF X.b 操作引用了已经从 Y.b 操作导出的消息元素 [http://tempuri.org/:b]。可以通过更改方法名称或使用 OperationContractAttribute 的 Name 属性更改其中一个操作的名称...

    详细错误如下: 很可能由 IncludeExceptionDetailInFaults=true 创建的 ExceptionDetail,其值为: System.InvalidOperationExc ...

  5. Python3 WebDriver操作cookie的方法

    Python3 WebDriver操作cookie的方法 WebDriver提供了操作Cookie的相关方法,可以读取.添加和删除cookie信息. WebDriver操作cookie的方法: get ...

  6. js操作cookie(创建、读取、删除)方法总结

    js操作cookie,可以通过开源的插件实现,方便快捷,兼容性好,同样也可以自己写: 此文主要介绍两个常用的插件: Js.cookie.js 和 jQuery.cookie.js 0.Js.cooki ...

  7. asp.net中HttpCookie操作cookie的方法

    微软对HttpCookie的定义为"提供创建和操作各 HTTP Cookie 的类型安全方法." HttpCookie的构造函数一共有两个 1.HttpCookie(String) ...

  8. jquery操作cookie {分享}

    web开发过程中如果网站有一部分信息是存储在cookie中并与服务器交互的话,那么前台有时就会遇到需要对cookie中信息进行操作的情况,一个最典型的例子就是在前台判断用户是否登录过当前所访问的网站. ...

  9. Android webview 写入cookie的解决方法以及一些属性设置

    原文地址:https://www.2cto.com/kf/201703/616868.html Android webview 写入cookie的解决方法以及一些属性设置,webview怎么设置写入C ...

随机推荐

  1. CSS Multiple Columns

    CSS Multiple Columns CSS layout column-count column-gap column-rule-style column-rule-width column-r ...

  2. Chrome & targetText

    Chrome & targetText target text http://www.ruanyifeng.com/blog/2019/03/weekly-issue-47.html http ...

  3. Flutter: moor_flutter库,简化sqlite操作

    入门 video moor_flutter 示例代码仓库 install dependencies: ... moor_flutter: dev_dependencies: ... moor_gene ...

  4. 1. VUE介绍

    今天开始系统学习vue前端框架. 我是有前端基础的, 刚工作那会, 哪里分那么清楚啊, 前后端我都得做, 所以, css, js, jquery, bootstrap都会点, 还系统学过ext, 哈哈 ...

  5. K8S部署Redis Cluster集群

    kubernetes部署单节点redis: https://www.cnblogs.com/zisefeizhu/p/14282299.html Redis 介绍 • Redis代表REmote DI ...

  6. 防抖和节流及对应的React Hooks封装

    Debounce debounce 原意消除抖动,对于事件触发频繁的场景,只有最后由程序控制的事件是有效的. 防抖函数,我们需要做的是在一件事触发的时候设置一个定时器使事件延迟发生,在定时器期间事件再 ...

  7. 1047 Student List for Course ——PAT甲级真题

    1047 Student List for Course Zhejiang University has 40,000 students and provides 2,500 courses. Now ...

  8. js引入jquery问题

    写jsp的时候明明已经引入了jquery组件,但是总是报错如下图 jsp代码如下 <%@ page language="java" contentType="tex ...

  9. The last packet successfully received from the server was 49,061,696 millise

    解决连接:https://blog.csdn.net/pandajava/article/details/41946251

  10. 在16G笔记本上安装GaussDB 200

    云主机太贵(最便宜的每月几千吧),长期如果需要GaussDB200有个功能测试或学习环境,那么性价比最高的方式还是在自己的笔记本电脑上尝试安装一个本地的数据库进行学习和功能验证. 01 安装环境信息 ...