首页 前端开发 Web前端入门第 81 问:JavaScript cookie 的读写操作

Web前端入门第 81 问:JavaScript cookie 的读写操作

前端的 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 保存敏感数据时,请务必注意数据安全,比如存储用户的身份令牌,如果身份令牌被三方代码获取,及其容易造成跨站请求伪造,导致用户信息泄露!!

站星网

前端的 cookie 读写在 2020 年之前一直不存在一个官方的接口,每次需要使用 cookie 的时候,要么是引入三方..

为您推荐

Web前端入门第 79 问:JavaScript async & await 的异步任务进化之路

JS 中异步任务随处可见,比如:1、用户交互的点击、输入2、网络请求的 fetch、ajax、WebSocket3、资源中的图片、脚本加载4、定时任务 setTimeout、setInterval、动画5、Web Worker 中的后台任务以上这些地方都能见到..

Web前端入门第 78 问:JavaScript 比较少见的模版字符串用法

在 ES6 之前,JS 的多行字符串一直是开发难题,在处理多行字符串时,各种各样的方案都有~~在 JS 中,如果直接这样写多行字符串:const str1 = '第一行第二行';那浏览器转过来就打脸,分分钟报错:Uncaught S..

Web前端入门第 76 问:JavaScript 鼠标事件(mouse) enter/leave 和 over/out 区别

题外话在考察事件基础的时候,会经常被问及 click、mousedown、mouseup 它们三者执行的先后顺序是怎样的?如果平时没太注意,这细节可能就会忽略,毕竟很少会在同一个元素上面同时绑定这三个事件~~直接上示例:<div ..

Web前端入门第 67 问:JavaScript 中的面向对象编程

此 对象 非彼对象啊,不要理解错了哦~~面向对象编程 这个概念在 Java 编程语言中用得比较多,JS 同时支持 面向对象编程 和 函数式编程。像大名鼎鼎的 React 和 Vue 他们都有两种开发风格,比如:Vue 中的 组合式API ..

Web前端入门第 57 问:JavaScript 数据类型与类型转换

在程序语言中,数据类型是基础,一切程序都是建立在基础数据之上。如果说程序如同万丈高楼平地起,那么数据类型就像沙、石、钢筋、水泥等等最基础的原料。一样的高楼,不同的人,用相同的原料,造的方法也会有千般变..

JavaScript实现图片上传预览及获取图片尺寸和大小的完整指南

在现代Web开发中,提供图片上传的预览功能以及获取图片的尺寸和大小信息,已成为提升用户体验的重要手段。本文将详细介绍如何使用JavaScript实现这些功能,帮助你在用户上传图片前进行有效的验证和优化。一、实现图..

Web前端入门第 60 问:JavaScript 各种数组定义与数组取值方法

数组可以算是程序里面最常用的数据结构了,但凡网页上任何一个列表数据,基本都是以数组的形式存在,像表格、banner图、菜单列表、商品列表,分类列表等等,在前端领域都是以数组处理。数组的定义JS 的数组花样很多..

Web前端入门第 55 问:JavaScript 严格模式与非严格模式区别

JavaScript 默认是非严格模式的,可以通过 "use strict"; 启用严格模式。此声明语句可以放在 JS 文件顶部,也可以放在函数内部。启用严格模式1、外部脚本在 JS 文件开头声明,内部脚本在 <script> 标签开头声明,声..

Mysql跨库操作

在 MySQL 中,操作多数据源(例如从库 A 和库 B)进行联查的情况,可以分为以下两种场景:A 库和 B 库在同一个 MySQL 实例当 A 库和 B 库在同一个 MySQL 实例下时,可以直接使用跨库联查查询。示例如下:SELECT A.co..

Web前端入门第 53 问:JavaScript 的各种调试方法

任何一门编程语言,在学习之前都应该先弄清楚它的调试方法,毕竟没有不挖坑的人类!程序一旦出现问题,第一时间就是找到问题出在哪儿,其次才是拿出解决办法。如果都找不到问题原因,那又何从谈起解决办法呢?如何排..

Web前端入门第 54 问:JavaScript 3 种书写位置及 script 标签的正确存放位置

JS 的代码并没有强制规定放在 HTML 中的某个位置,如果您有使用过开发者工具查看过网页源码,那么您会看到很多 JS 代码都以 .js 文件的形式存放,并且放在了 HTML 文件最后,也就是 </body> 结束标签之前。但如果仔..

Web前端入门第 52 问:JavaScript 的应用领域

截至目前,您应该对前端的 HTML + CSS 应该有了很清楚的认知,至少实现一个静态网页已经完全不在话下了。当然,CSS 功能绝不止这些,一些不太常用的 CSS 相关知识,后续将通过案例进行分享。那么咱们接下来看看 Java..

.NET C# 过滤从富文本编辑器html里的Javascript脚本

富文本编辑器在允许用户输入丰富内容的同时,也带来了跨站脚本攻击(XSS)的风险。过滤提交的 HTML 中的 <script> 脚本是防止跨站脚本攻击(XSS)的关键步骤。在 .NET C# 服务端过滤 <script> 脚本主要有以下几种方..

轻松学习 JavaScript函数中的默认参数

JavaScript函数可以有默认参数值。通过默认函数参数,你可以初始化带有默认值的正式参数。如果不初始化具有某些值的参数,则该参数的默认值为undefined。请看下列代码:function foo(num1){console.log(num1);}foo()..

.NET CORE 设置cookie以及获取cookie

使用我这个方式的前提是在mvc中,确认你安装了:Microsoft.AspNetCore.Mvc.然后在继承了Controller的类型中使用我所说的方法。直接使用即可,我是封装了方法供我自己使用,代码如下: public abstract class Control..

JavaScript API 设计原则详解

前言本篇博文来自一次公司内部的前端分享,从多个方面讨论了在设计接口时遵循的原则,总共包含了七个大块。系卤煮自己总结的一些经验和教训。本篇博文同时也参考了其他一些文章,相关地址会在后面贴出来。很难做到详..

JavaScript 中精度问题以及解决方案

JavaScript 中的数字按照 IEEE 754 的标准,使用 64 位双精度浮点型来表示。其中符号位 S,指数位 E,尾数位M分别占了 1,11,52 位,并且在ES5 规范中指出了指数位E的取值范围是[-1074, 971]。精度问题汇总想用有限..

JavaScript 六种继承方式

继承是面向对象编程中又一非常重要的概念,JavaScript支持实现继承,不支持接口继承,实现继承主要依靠原型链来实现的。原型链首先得要明白什么是原型链,在一篇文章看懂proto和prototype的关系及区别中讲得非常详细..

JavaScript 事件委托详解

基本概念事件委托,通俗地来讲,就是把一个元素响应事件(click、focus……)的函数委托到另一个元素;一般来讲,会把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,当事件响应..

JavaScript 中的遍历详解

编程这么多年,要是每次写遍历代码时都用 for 循环,真心感觉对不起 JavaScript 语言~对象遍历为了便于对象遍历的测试,我在下面定义了一个测试对象obj。测试对象// 为 Object 设置三个自定义属性(可枚举)Object.p..

发表回复

返回顶部

微信分享

微信分享二维码

扫描二维码分享到微信或朋友圈

链接已复制