目录
cookie 是什么?
http 是一种无状态协议,就是一种不保存状态的协议,一个服务器不清楚是不是同一个浏览器在访问它。为了解决 http 无状态的特点,会在请求中插入 token,然后发送请求,告诉服务器,但是这种方式容易出错。为了解决技术 token 的缺陷,cookie 就出现了。
http 协议中的 cookie 包括 web cookie 和浏览器 cookie,是服务器发送到 web 浏览器的一小块数据,保存在浏览器的一小段文本信息,浏览器进行存储并且下次发送请求的时候携带上 cookie。浏览器每次向服务器发送请求都会携带这段信息。用于判断了两个请求是否来自于同一个浏览器。
cookie 是一种浏览器管理状态的一个文件,它有 name、value,Domain、path 等等。
cookie 不可以跨域请求
javascript:document.cookie='myname=Jasmine;path=/;domain=.baidu.com';
javascript:document.cookie='myname=Jasmine;path=/;domain=.csdn.net';
在当前页面 F12 打开控制台,输入上面两个语句,查看 cookie 如下
解析:只有 domain 是 csdn.net 的 cookie 绑定到了域名上面。所以证明了 cookie 不可以跨域请求,不能在不同的域名下用。
cookie 的属性
属性名 | 描述 |
Name | cookie 的名字,一个域名下绑定的 cookie 的 name 不能相同。如果是相同的 name 则会被覆盖 |
Value | 表示 cookie 对应属性的值。 由于 cookie 规定是名称/值是不允许包含分号,逗号,空格的,所以为了不给用户到来麻烦,考虑服务器的兼容性,任何存储 cookie 的数据都应该被 URL 编码 |
Domain | cookie 的域名。cookie 绑定的域名,如果没有设置,自动绑定当前执行语句的的域。同一个域名下的二级域名也是不可以交换 cookie 的 |
Path | path 是默认属性 '/',匹配 web 路由 路径设置 /blog 的时候,也会给 /blog 绑定 cookie |
Expires / Max-Age | expires 是 cookie 的有效期。一般浏览器的 cookie 是默认存储的,关闭浏览器结束会话,cookie 就会被删除。 如果想要 cookie 续存一段时间,可以通过设置expires有效期。 expires 现在被 Max-Age 取代:Max-Age,是以秒为单位的
|
Secure | 安全。http 无状态无加密,不安全协议容易被攻击挟持,比如在浏览页面的时候会有小广告出来。 secure 属性为 true 的时候,这个时候的 cookie 只会在 https 和 ssl 等安全协议下传输。不能对cookie 加密,绝对安全保证做不到 |
httpOnly | 安全的 Cookie 需要经过 HTTPS 协议通过加密的方式发送到服务器。即使是安全的,也不应该将敏感信息存储在cookie 中,因为它们本质上是不安全的,并且此标志不能提供真正的保护。 作用:
|
会话cookie & 永久性cookie
cookie有两种类型,取决于是否含有到期日期。
- Session Cookies(会话cookie)
客户端关闭,数据删除,永久丢失。没有指定的 Expires/Max-Age 指令,存储在内存。
ps:Web 浏览器可以让会话还原,可以让大多数会话 cookie 数据保持永久性,像浏览器永远没有关闭一样。
- Persistent Cookies(永久性cookie)
客户端关闭,数据不会删除。当 Expires/Max-Age 过期,才会删除数据,存储在磁盘。
cookie 禁用
cookie 可能被禁用,当用户非常注重隐私的时候,可以禁用浏览器的 cookie 功能。比如 SessionID 通过 cookie 存储在客户端,如果 cookie 被禁用,必然会造成 Session 使用的影响。
解决方法:URL 重写
- servlet 中涉及客户端输出页面元素的时候,在相应的请求地址外面加一层方法,response.encodeURL('URL'),为请求地址添加 JSESSIONID 的值
- servlet 跳转页面,使用 response.encodeRedirectURL('URL'),为请求地址添加 JSESSIONID的值
- JSessionID 是一个用于 Web 应用程序的会话标识符,主要用于保持用户会话的状态
cookie 的应用
- 会话管理
登录验证、购物车、游戏得分或者其他服务器应该记住的状态。
登录验证:用户在第一次登录某个网站时,要输入用户名密码,如果觉得很麻烦,下次登录时不想输入了,那么就在第一次登录时将登录信息存放在 cookie 中。下次登录时我们就可以直接获取 cookie 中的用户名密码来进行登录。浏览器将信息保存在 cookie 中是加密的,但是不是绝对安全,也有造成不安全的信息泄漏的可能。
购物车:类似于购物车性质的功能,第一次用户将某些商品放入购物车了,但是临时有事,将电脑关闭了,下次再次进入此网站,我们可以通过读取 cookie 中的信息,恢复购物车中的物品。现在基本很少用,都是存储在数据库中,通过查询数据库来恢复购物车信息。
- 个性化定制
用户的个性化定制主题,用户的偏好
- 追踪
记录分析用户行为。Cookie 曾经是客户端存储数据的唯一方式,如今改进用 API。cookie 每个请求都携带会大大降低性能,尤其是对于移动数据的链接。
- 页面传值
在实际开发中,我们往往会通过一个页面跳转到另外一个页面。后端服务器我们可以通过数据库,session 等来传递页面所需要的值。但是在浏览器端,我们可以将数据保存在 cookie 中,然后在另外页面再去获取 cookie 中的数据。cookie 的数据具有时效性,注意过期日期,不然会造成数据混乱。
sessionStorage 是什么?
sessionStorage 是 HTML5 新增的一个会话存储对象,用于临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据。
失效时间
sessionStorage 的生命周期仅在当前会话有效。sessionStorage 引入了“浏览器窗口的概念”。sessionStorage 在同源窗口中始终存在数据,只要浏览器窗口没有关闭,刷新或者重新进入页面数据依然存在。关闭浏览器窗口后数据会被删除。再次独立打开同一个窗口同一个页面,sessionStorage 也是不一样。
存储内容的类型
sessionStorage 只能存储字符串类型,对于复杂对象可以使用 ECMAScript 对象的 stringify 和parse 处理。
- Q1:存储是对象,为什么value对应的是['Object Object']呢?
解决问题:sessionStorage.setItem('tg',JSON.stringify(person))
- Q2:尝试获取数据,取出的是string类型
解决问题:const changeResult = JSON.parse(sessionStorage.getItem('tg'))
// Q
const person = {name: 'Jasmine', age: 18}
sessionStorage.setItem('person', person)
sessionStorage.getItem('person')
// '[object Object]'
// 解决办法
sessionStorage.setItem('person', JSON.stringify(person))
JSON.parse(sessionStorage.getItem('person'))
// {name: 'Jasmine', age: 18}
总结:通过转成字符串的形式存储,取出的时候转成对象,就能正常的存储和读取。
存储的大小
sessionStorage 存储数据大小一般是 5MB
存储的位置
sessionStorage 都保存在客户端,一般不与服务器进行通信交互。
sessionStorage 的应用
敏感账号一次性登录
localStorage 是什么?
失效时间
localStorage 的生命周期是永久的,关闭页面或者浏览器之后 localStorage 中的数据也不会消失。localStorage 删除数据要手动删除,否则数据永远不会消失。
存储内容的类型
localStorage 只能存储字符串类型,对于复杂对象可以使用 ECMAScript 对象的 stringify 和 parse 处理。
存储的大小
localStorage 存储数据大小一般是 5MB
存储的位置
localStorage 都保存在客户端,一般不与服务器进行通信交互。
localStorage 的应用
常用于长期登录、判断是否已登录、适合长期保存在本地的数据。
惰性删除、定时删除
- 惰性删除:某个键值过期后,该键值不会被马上删除,而是等到下次被使用的时候,才会被检查到过期,此时才能得到删除。
缺点:惰性删除已经实现可过期的 localStorage 缓存,但是也有明显的缺点。如果一个key一直没有被用到,就不会被及时检查,即使过期了也一直存在 localStorage
- 定时删除:每隔一段时间执行一次删除操作,并通过限制删除操作执行的次数和频率,来减少删除操作对 CPU 的长期占用。另一方面定时删除也有效的减少了因惰性删除带来的对 localStorage 空间的浪费。
每隔一秒执行一次定时删除,操作如下:
- 随机测试20个设置了过期时间的 key
- 删除所有发现的已过期的 key
- 若删除的 key 超过5个则重复步骤1,直到重复500次
localStorage 的限制
- IE8 以上版本才支持 localStorage 这个属性
- 目前主流浏览器中都会把 localStorage 的值类型限定为 string 类型,这个对我们日常比较常见的 JSON 对象类型需要一些转换
- localStorage 在浏览器的隐私模式下不可读取
- localStorage 本质上是对字符串的读取。如果读取内容多的话会消耗内存空间,导致页面卡
- localStorage 不会被爬虫爬取到数据
cookie & sessionStorage & localStorage
cookie | localStorage | sessionStorage | |
存储大小 | 4KB | 一般5M | |
与服务端通信 | 每次都会携带在 HTTP 头中,如果使用 cookie 保存过多数据会带来性能问题 | 仅在客户端中保存,不参与和服务器的通信 | |
存储格式 | 字符串格式 | 键值对 | |
操作相关 | 操作复杂,无api 前后端都可操作 | 操作简单,有api 只能前端操作 | |
时效 | 默认会话级别 可设置失效时间 | 永久存储 手动删除后才会清除 | 会话存储 关闭窗口后被清除 |
用途 | 一般由服务器端生成,用于标识用户身份 | 用于浏览器端缓存数据 |