当前位置: 首页 > 后端技术 > Node.js

一个原生的操作cookies的方法cookieStore

时间:2023-04-03 13:31:30 Node.js

TNTWeb-全称是腾讯新闻前端团队。群里的小伙伴在Web前端、NodeJS开发、UI设计、手机APP等大前端领域都有实践和积累。目前团队主要支持腾讯新闻各项业务的前端开发。除了业务发展,它还积累了一些前端基础设施,以实现业务效率提升和产品创新。团队倡导开源共建,拥有各类技术人才。团队Github地址:https://github.com/tnfe本文作者wenzi0github我们在增删改查cookies的时候,一般都会操作document.cookie。这里我们引入一个新的方法cookieStore。1、平时如何操作cookiedocument.cookie可以获取当前域下所有的cookie字符串。每个cookie由分号分隔:document.cookie;//"a=1;b=2;c=wenzi"操作的是cookie,也就是操作document.cookie。比如下面是我经常用到的一段代码:/***写cookie*@param{string}name写cookie的key*@param{string|number}value写cookie的值*@param{number}day存储时间,默认30天*/exportconstsetCookie=(name:string,value:string|number,day=30):void=>{constexp=newDate();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是否直接获取对应的值,如果存储的是真值则直接返回,否则解码*/exportconstgetCookie=(名称:字符串):字符串|null=>{constreg=newRegExp(`(^|)${name}=([^;]*)(;|$)`);constarr=文档。cookie.match(注册);如果(arr){返回unescape(arr[2]);}returnnull;};/***deletecookie*@paramname删除的cookie的名称*/exportconstdelCookie=(name:string)=>{if(!name)return;constex:Date=newDate();ex.setTime(ex.getTime()-1);document.cookie=`${name}=;过期=${ex.toUTCString()};path=/`;};可以看到cookie的设置、获取、删除都是在document.cookie上操作的2.新方法cookieStore现在Chrome有更方便的操作cookies的方式cookieStore,这个方法是Chrome87版本新增的,兼容性不是很好好的。下图是当前日期2021/03/15的兼容性概览。可以发现只有Chrome系统支持cookieStore。不过我们可以先了解一下它的用法。cookieStore在https协议下只能通过域名访问;其他http协议的域名会提示cookieStore未定义,或者设置失败。2.1基本方法cookieStore是一个类似于localStorage的对象类型变量。可以看到cookieStore主要有5个方法:set:设置cookie,可以是set(name,value)或者set({name,value});get:获取cookie,可以是get(name),也可以是get({name});getAll:获取所有cookie;删除:删除cookie;onchange:监听cookie的变化;前4个方法自然支持Promise。接下来,我们就来一一了解。2.2设置cookiecookieStore.set方法可以设置cookie并返回一个Promise状态,表示设置是否成功。cookieStore.set('用户名','文子').then(()=>console.log('设置用户名成功')).catch(()=>console.error('设置用户名失败'));if我们要设置更多的属性,比如过期时间,可以传入一个Object类型:cookieStore.set({name:'age',value:18,expires:newDate().getTime()+24*60*60*1000,}).then(()=>console.log('设置年龄成功')).catch(()=>console.error('设置年龄失败'));value中的所有数据都会默认先执行toString(),然后再存储,所以最好先转换一些非基本类型的数据。以上是我们成功设置cookie的情况,那么什么时候会设置失败呢?在本地localhost环境下,设置会失败。本地localhost,我们可以获取到cookieStore的全局变量,也可以执行相应的方法,但是无法设置成功:cookieStore.set('username','wenzi');浏览器会提示,不能设置在不安全的域名中接下来通过setinCookieStore设置cookie:Uncaught(inpromise)TypeError:Failedtoexecute'set'on'CookieStore':Cannotmodifyasecurecookieoninsecureorigin添加catch后,可以捕获到这个错误:cookieStore.set('username','wenzi').then(()=>console.log('setusernamesuccessfully')).catch(()=>console.error('设置用户名失败'));所以想用cookieStore这种情况下,不能直接用下面的方法判断,而是要增加一个新的页面url协议来判断:typeofcookieStore==='object';//如果判断不准确,本地localhost也会存在。应该使用:constisSupportCookieStore=typeofcookieStore==='object'&&location.protocol==='https:';//CookieStore2.3仅在https协议下使用获取cookiescookieStore.get(name)方法可以获取name对应的cookie,会以Promise格式返回所有属性:awaitcookieStore.get('username');get()方法也可以接收Object类型。经过测试发现key的值只能是name:awaitcookieStore.get({name:'username'});当获取的cookie不存在时,返回一个Promise。2.4获取所有cookiescookieStore.getAll()方法可以获取当前所有的cookies,并以Promise<[]>的形式返回。数组中的每一项与通过get()获得的一项格式相同;如果当前域没有cookie,或者无法获取指定的cookie,则为空数组;等待cookieStore.getAll();getAll()方法也可以传入一个name来获取对应的cookie:awaitcookieStore.getAll('username');awaitcookieStore.getAll({name:'username'});2.5删除cookiecookieStore.delete(name)is用于删除指定的cookie:cookieStore.delete('age').then(()=>console.log('删除年龄成功')).catch(()=>console.error('删除年龄失败'));删除成功后会提示删除成功。即使删除不存在的cookie,也会提示删除成功。所以再次执行上面的代码时,还是会正常提示。同样,在localhost环境下,会提示删除失败。2.6监听cookie的变化我们可以通过添加change事件来监听cookie的变化,无论是通过cookieStore操作还是直接操作document.cookie,我们都可以进行监听。添加监听事件:cookieStore.addEventListener('change',(event)=>{consttype=event.changed.length?'change':'delete';constdata=(event.changed.length?event.changed:event.deleted).map((item)=>item.name);console.log(`刚刚执行了${type}操作,cookie有:${JSON.stringify(data)}`);});这里有2个重要字段更改数组和删除数组。设置cookie时,changed数组包含刚刚设置的cookie;删除cookie时,deleted数组包含刚刚删除的cookie。2.6.1设置操作当调用set()方法时,会触发change事件,将受影响的cookie放入event.changed数组中。通过document.cookie设置或删除的cookie被认为是修改cookie,而不是删除它们。每设置一个cookie,即使两次name和value完全一样,也会触发change事件。cookieStore.set('数学',90);2.6.2删除操作当通过delete()方法删除已有的cookie时,会触发change事件,将删除的cookie放在event.deleted数组中。如果删除不存在的cookie,则不会触发change事件。cookieStore.delete('数学');可以看到第二次删除名为math的cookie时,并没有触发change事件。3.小结我们通过这篇文章了解了cookieStore的使用和操作,这比直接操作cookie要简单的多,而且我们还可以通过它自身的change事件来监听cookie的变化。