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

浅谈http协议(二):cookie的历史由来与实际应用

时间:2023-04-04 01:19:25 Node.js

浅谈http协议(二):cookies的历史渊源与实际应用记录其最后的请求信息。那么问题来了,开发中经常用到状态记录,比如每天登录网站,不可能每次登录都让客户重新输入密码,这样用户体验肯定会很差,所以如何让无状态的http协议记录呢?于是浏览器厂商发明了cookie来解决这个问题。Cookie始终保存在客户端中。根据在客户端的存储位置,可分为内存cookies和硬盘cookies。过期时间设置为Expires(cookie的几个属性之一)的cookie将存储在硬盘中。操作系统cookie的存储路径会有所不同,没有该属性的cookie会存储在内存中。此时浏览器的标签页可以共享相同的cookie信息,关闭浏览器时cookie会被清除!先看cookie在前后端交互中的应用:第一次验证成功后,服务端会在响应头信息中包含“set-cookie”字段。浏览器检测到该字段后,会检查其中的值。写入浏览器的cookie的属性中存储在cookie中的数据,每次过期前都会被浏览器自动放入http请求中。如果数据不是每次请求都需要发送给服务器的数据,浏览器设置的自动处理无疑会增加网络开销;但如果每次请求都需要向服务器发送数据(如身份认证信息),浏览器设置的自动处理将大大避免重复添加操作。所以对于设置“每次请求中必须携带的信息(最典型的就是身份认证信息token)”来说特别适合放在cookie中。服务器端通过验证cookie中的信息来实现验证,这样也省去了浏览器每次输入登录信息的麻烦。为了实现cookie的作用,除了name和value之外,设计者还为其添加了七个属性,分别是expires/max-age、domain、path、secure、HttpOnly、samesite,这些属性是通过cookie选项设置的,这些属性可以在设置任何cookie的时候设置,也可以不设置,都会使用这些属性的默认值。Expires和Max-Ageexpires选项用于设置“cookie的有效期”。expires实际上是cookie的过期日期,expires必须是GMT格式的时间(可以通过newDate().toGMTString()或newDate().toUTCString()获取)。例如expires=Thu,25Feb201604:18:00GMT表示cookie将于2016年2月25日4:18后过期,浏览器会清除过期的cookie。如果不设置该选项,则默认有效期为session,即sessioncookie。这种cookie在浏览器关闭后消失,属于记忆cookie。而max-age是cookie写入后生效的时间,例如max-age=600表示cookie将在600秒后过期。max-age的优先级高于expires。domain和path是域名,path是路径。两者的组合形成一个URL。域和路径一起限制了可以访问cookie的URL。domain属性的默认值是创建cookie的网页所在服务器的主机名。您不能将cookie的域设置为服务器所在域以外的域。如果想让cookie在多个二级域名中共享,需要将domain设置为顶级域名。HttpOnly通过脚本document.cookie告诉浏览器不允许更改这个值,并且这个值在document.cookie中也是不可见的。但是这个cookie还是会携带在http请求表中。请注意,尽管该值在脚本中不可用,但它仍然作为文件存在于浏览器安装目录中。secure安全标志,指定后,只能在使用SSL连接(https)时发送给服务器,如果是http连接,则不会传递信息。即使设置了secure属性,也不代表别人看不到你机器本地保存的cookie信息,所以不要把重要信息放在cookie里。samesite添加的cookie属性主要是为了防御CSRF攻击(跨站请求伪造)。SameSite=Strict严格模式表示这个cookie在任何情况下都不能作为第三方cookie使用。有兴趣的可以查看“csrf攻击”除了服务器返回的set-cookie字段外,浏览器也可以对cookie进行操作。有npm打包的插件js-cookie:https://www.npmjs.com/package...,但是我们还是使用native方式手动获取cookies:在控制台输入document.cookie,或者consolejs代码中的.log(document.cookie)得到如下图:可以看到cookies是键值对("key=value")加上一个分号和一个空格分隔的组合,形式是这样的:"name1=value1;name2=value2;name3=value3",可以用正则表达式提取等号后的值functiongetCookie(name){varvalue=';'+文件.cookie;varparts=value.split(';'+name+'=');if(parts.length===2){returnparts.pop().split(';').shift();}}writecookiefunctionsetCookie(name,value,day){if(day!==0){//当设置时间等于0时,不设置expires属性,cookie在浏览服务器后删除已关闭varexpires=day*24*60*60*1000vardate=newDate(+newDate()+expires);document.cookie=name+"="+escape(value)+";expires="+date.toUTCString()}else{document.cookie=name+"="+escape(value)}}注意:expires使用GMT或UTC格式的时间,我这里没有有一个指定的路径(path)和域(domain)。当没有指定路径时,默认为当前路径。例如在“https://home.cnblogs.com/u/ma...”下设置的cookie,其路径为“/u/maderlzp”,其域为当前域名“home.cnblogs”。com”删除cookie,设置cookie过期时间小于当前时间,则cookie将被删除functiondeleteCookie(name){document.cookie=name+'=;expires=Thu,01Jan197000:00:01GMT;'}Cookie是非跨域的。根据cookie规范,访问Google.com的浏览器只会携带Google.comcookies,不会携带Baidu.comcookies。.Google.com只能操作Google.comcookie,不能操作Baidu.comcookie<完>