前端的 cookie 读写在 2020 年之前一直不存在一个官方的接口,每次需要使用 cookie 的时候,要么是引入三方插件,要么就需要自己封装一个公用的组件或函数。

npm 的 cookie 插件周下载量 6 千万左右,可以想象一下此功能在前端的应用场景有多么广泛~~

cookie 插件: https://www.npmjs.com/package/cookie

cookie 用途

cookie 一般多用于存储标识符,比如用户身份标识(登录状态),个性化设置的一些标识(语言设置,主题设置等等),用户行为跟踪标识(跟踪用户点击行为等)。

以前还有很多的广告商用于跟踪用户行为,现在由于浏览器的安全机制越来越严格,广告商基本不再使用 cookie 跟踪用户信息,转而使用浏览器的指纹特征来做跟踪记录。浏览器指纹可参考文章:浏览器 15 个常见指纹特征,使用插件 FingerprintJS 生成浏览器指纹

cookie 安全问题

由于 cookie 存储在用户浏览器,极易被嵌入的三方代码获取,用于 XSS 攻击,CSRF 跨站请求伪造等等。

所以在使用 cookie 存储关键信息时候,需要注意配置 cookie 的安全属性,比如:过期时间(expires)、安全(secure)、sameSite等。

cookie 相关属性

name:记录 cookie 名称的字符串。

value:记录 cookie 值。

domain:表示 cookie 的所属域,跨域不能访问。

expires:表示 cookie 的过期时间,使用 unix 时间戳,不设置默认是会话结束,即浏览器关闭就失效。

path:记录 cookie 路径的字符串,设置了路径之后,跨路径无法访问。默认为 /。

partitioned:cookie是否分区,实验性质。

sameSite:设置跨站点请求中是否发送cookie。

secure:设置后表示只能通过 HTTPS 协议访问。


以下属性仅支持后端设置,前端无法处理。

httpOnly:设置后客户端脚本(即浏览器端)无法访问 cookie。

cookie 存储方法

最原始的 cookie 存储方法只能使用 document.cookie 属性,读写操作都只能通过它~~

例如一个完整的设置 cookie 的代码:

document.cookie = `name=${encodeURIComponent('前端路引')};expires=${new Date(2026, 0, 1).toGMTString()};path=/;Secure;SameSite=Lax`;

注意:写入 cookie 的属性值不能存在换行,换行无效,代码也不会报错,比如:

// 由于有换行符存在以下代码浏览器不报错,也不会写入cookie
document.cookie = `
name=${encodeURIComponent('前端路引')};
expires=${new Date(2026, 0, 1).toGMTString()};
path=/;
domain=localhost;
Secure;
SameSite=Lax
`;

取值:

const name = document.cookie.split(';').find(item => item.trim().startsWith('name=')).split('=')[1]
console.log(decodeURIComponent(name))

这种读写方法始终不太方便,然后可以稍稍的封装一下:

/**
* 获取或者设置cookie
* @param name {String} cookie名
* @param value {String} cookie值,如果传递该参数,则直接取值
* @param days {Number} 设置cookie有效天数
* @return 如果取值,则返回值,没值则返回null
*/
function cookie (name, value, days) {
if (value !== undefined) {
if (days === undefined || days === null || days === '') {
document.cookie = name + '=' + encodeURIComponent(value) + '; path=/;';
return;
}
days = isNaN(days) ? 0 : days;
var exp = new Date();
exp.setTime(exp.getTime() + days * 24 * 60 * 60 * 1000);
document.cookie = name + '=' + encodeURIComponent(value) + '; path=/;expires=' + exp.toGMTString();
} else {
var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)');
var arr = document.cookie.match(reg);
if (arr) {
return decodeURIComponent(arr[2]);
} else {
return null;
}
}
}

以上代码只是一个基础的封装使用,可以基于此扩展一下其他配置项!!也可以直接下载 npm 开源的 cookie/js-cookie 插件。

CookieStore

document.cookie 操作 cookie 需要对字符串进行处理,如果存在多个 cookie 的情况下,处理起来就更麻烦,所以在 2020 年 JS 标准就新增了 CookieStore 接口,用于管理 cookie。此接口大大的简化了 cookie 的读写操作,用起来也更加方便。

CookieStore 只能在 https 或者 localhost 下使用,所以不再支持 Secure 配置,默认就是在 https 中传输。

CookieStore 对象就四个方法,都返回 Promise 对象:

// 删除
cookieStore.delete() // 返回 Promise
// 获取
cookieStore.get() // 返回 Promise
// 获取全部
cookieStore.getAll() // 返回 Promise
// 写入
cookieStore.set() // 返回 Promise // 支持change事件用于监听 Cookie 变化
cookieStore.addEventListener("change", (event) => { })
cookieStore.onchange = (event) => { }

使用示例:

(async () => {
cookieStore.addEventListener("change", (event) => {
console.log(event.changed);
})
cookieStore.onchange = (event) => {
console.log(event.changed);
} await cookieStore.set('name', '公众号')
await cookieStore.get('name').then(value => {
console.log(value)
})
await cookieStore.delete('name').then(() => {
console.log('删除成功')
})
await cookieStore.set({
name: 'name',
value: '前端路引',
expires: new Date(2026, 0, 1).getTime(), // Unix 时间戳(以毫秒为单位表示)
path: '/',
secure: true, // 不支持设置
sameSite: 'lax'
})
await cookieStore.get({
name: 'name',
url: window.location.href
}).then(value => {
console.log(value)
})
await cookieStore.set('type', '公众号')
await cookieStore.getAll().then(values => {
console.log(values)
})
})()

更多用法参考 MDN 文档:https://developer.mozilla.org/zh-CN/docs/Web/API/CookieStore

写在最后

cookieStore 可以大大简化前端读写 cookie 的复杂度,但由于其 API 引入时间较晚,基本都是在 2020 年之后的浏览器才开始支持,所以在使用时请注意浏览器兼容情况。

在使用 Cookie 保存敏感数据时,请务必注意数据安全,比如存储用户的身份令牌,如果身份令牌被三方代码获取,及其容易造成跨站请求伪造,导致用户信息泄露!!

Web前端入门第 81 问:JavaScript cookie 的读写操作的更多相关文章

  1. web前端入坑第五篇:秒懂Vuejs、Angular、React原理和前端发展历史

    秒懂Vuejs.Angular.React原理和前端发展历史 2017-04-07 小北哥哥 前端你别闹 今天来说说 "前端发展历史和框架" 「前端程序发展的历史」 「 不学自知, ...

  2. web前端入坑第二篇:web前端到底怎么学?干货资料! 【转】

    http://blog.csdn.net/xllily_11/article/details/52145172 版权声明:本文为博主[小北]原创文章,如要转载请评论回复.个人前端公众号:前端你别闹,J ...

  3. WEB前端工程师整理的原生JavaScript经典百例

    一.原生JavaScript实现字符串长度截取 二.原生JavaScript获取域名主机 三.原生JavaScript转义html标签 四.原生JavaScript时间日期格式替换 Date.prot ...

  4. web前端(13)—— 了解JavaScript,JavaScript的引入方式

    从本篇博文开始,将进入web前端方便最关键最重要的部分——javascript,学到后面你就知道它真的太重要了 什么是JavaScript JavaScript一种直译式的脚本语言,是一种动态类型.弱 ...

  5. Web前端基础怎么学? JavaScript、html、css知识架构图

    以前开发者只要掌握 HTML.CSS.JavaScript 三驾马车就能胜任一份前端的工作了.而现在除了普通的编码以外,还要考虑如何性能优化,如何跨端.跨平台实现功能,尤其是 AI.5G 技术的来临, ...

  6. web前端学习之HTML CSS/javascript之一

    前端编码之路之坎坷,web前端应该一直是个战场吧,各种浏览器的不兼容,各种小细节的修改,要往一个好的产品经理方向走,实在是难,昨天听了一位十年经验的产品经理讲座,最重要的恐怕就是协调资源的能力,而协调 ...

  7. Android零基础入门第81节:Activity数据传递

    在Android开发中,经常要在Activity之间传递数据.前面也学习了Activity和Intent相关基础,接下来一起来学习Activity的数据传递. 一.简介 通过前面的学习知道,Inten ...

  8. web前端学习(四)JavaScript学习笔记部分(1)-- JavaScript基础教程

    1.JavaScript基础教程 1.1.Javascript基础-介绍.实现.输出 1.1.1.JavaScript是互联网上最流行的脚本语言,这门语言可用于web和HTML,更可广泛用于服务端.p ...

  9. Web前端开发规范【HTML/JavaScript/CSS】

    前言 这是一份旨在增强团队的开发协作,提高代码质量和打造开发基石的编码风格规范,其中包含了 HTML, JavaScript 和 CSS/SCSS 这几个部分.我们知道,当一个团队开始指定并实行编码规 ...

  10. web前端——实例中学习css,javascript

    最近闲暇时候在研究前端的样式和js,以前都是从w3school上看看那些选择器和DOM操作方法很少去实际做demo来研究,做的过程当中才真切感觉到纸上得来终觉浅,看得懂跟能做出东西完全两码事,尤其在定 ...

随机推荐

  1. 使用Ollama本地化部署DeepSeek

    1.Ollama 简介 Ollama 是一个开源的本地化大模型部署工具,旨在简化大型语言模型(LLM)的安装.运行和管理.它支持多种模型架构,并提供与 OpenAI 兼容的 API 接口,适合开发者和 ...

  2. Stream.findFirst()代替get(0)和数组[0]获取集合中的第一个值

    一.介绍 语法 集合.stream().findFirst() 使用 // 我们的工具类(切割SKU字符串relatedSkuJoin,转为集合).stream.第一个数(): CommonUtils ...

  3. IT/互联网行业突围之路:ChatGPT驱动下的未来

    @charset "UTF-8"; .markdown-body { line-height: 1.75; font-weight: 400; font-size: 15px; o ...

  4. WPF在Visual studio中打包,发布注意事项

    右键项目,发布的时候,需要选择独立,否则依赖库的话,有可能客户端没有.net core或.net framework,那么就会报错,提醒对方下载. 今天发现,VS 2022,直接Debug运行后,Re ...

  5. C#之动态语言扩展

    DLR 在.NET Framework中,DLR2位于System.Dynamic命名空间和System.Runtime.CompilerServices命名空间的几个类中. dynamic 类型 可 ...

  6. 蓝桥杯2019java b组

    给定一个数列 1 1 1 3 5 9 17--,这个数列第四项开始等于前三项的和,让你求出第20190324项的最后四位数. package BlueCup; public class Main { ...

  7. 解决Navicat导出Excel数字为科学计数法问题

    问题分析 需求是使用Navicat导出数据到Excel中,但是,发现导出的数据中,数字长度如果超过12位,自动的按照科学计数法显示数字.我们需要全部显示输入的内容,而不能使用科学计数法,如输入的身份证 ...

  8. Scrum Master,这九个问题你问了吗?

    从团队技术负责人到Scrum Master或PO,我们需要从做决策转为提问题. 一.2个关于估算的问题 团队在进行项目前需要进行粗略估算,但这并不是要求团队成员一定按照估算出的结果进行. 问题一:估算 ...

  9. Error creating bean with name 'xxx' defined in file异常处理

    SpringBoot整合mybatis 今天在使用mybatis generator时遇到一个坑,出现以下错误 Error creating bean with name 'authorizeCont ...

  10. 03 - LayoutPanels例子 - SimpleInkCanvas

    C# maui暂时没有官方支持InkCanvas,但是不影响,自己实现一个就行了.目前支持,画图,选择,移动和删除.同时支持自定义橡皮擦形状,也支持绑定自定义的形状列表. 实现一个Converter类 ...