cookie session localStorage sessionStorage


啰嗦的话不说,直接上干货,概念性的东西,什么产生背景啥的自己组织一下语言就好了

session

session是用来在客户端与服务器之间保持状态的一种解决方案(由于http的无状态),主要特点:

  • 数据保存在服务端,session存在过期时间

  • 多数情况下session实现依赖cookie,通过cookie存放sessionId,也可通过URL编码的方式携带sessionId

  • session存放的数据的key不能为null(至少在java web中如此)

  • session存放的数据的value为null时视为删除操作(至少在java web中如此)

    放源码,来自apache tomcat的session实现类org.apache.catalina.session.StandardSession

cookie大小限制,最多4K。

cookie主要5大属性:

  • name:名称
  • value:值
  • domain:作用域,默认情况下,cookie的domain是设置该cookie的web服务器的域名,如domain域为.ccc.com的cookie可以被www.aaa.ccc.comwww.bbb.ccc.com的网站所读取,不能将一个cookie的域设置成服务器所在的域之外的域 ;cookie的domain属性不与端口相关,即同IP不同端口的web服务有机会获取到对方的cookie(path值匹配的话)
  • path:路径值;服务器后端获取cookie的规则:设当前URI为:/a/b,cookie路径为path,服务器后端能获取到的cookie满足:path.startsWith(URI) || URI.startsWith(path)
  • expires/max-age:过期时间/最大“年龄”;根据过期时间 max-age 有3种情况:
    • max-age > 0;cookie到期销毁,此时cookie存于磁盘
    • max-age = 0;cookie已经过期,此时cookie销毁
    • max-age < 0;cookie在关闭浏览器后销毁,此时cookie存于内存

另外还有两个属性值得关注:

  • secure:取值范围 true | false,是否仅支持https传输

  • SameSite:Chrome 51 开始,浏览器的 Cookie 新增加了一个SameSite属性,限制第三方 Cookie,用来防止 CSRF 攻击和用户追踪,该属性不在服务端体现(至少目前java web是这样)。取值范围:

    • Strict:完全禁止第三方 Cookie,任何跨域请求浏览器都不会发送cookie

    • Lax:次于Strict的限制级别,任何跨域大多数情况浏览器不会发送cookie,如下表

      请求类型 示例 Lax
      链接 <a href=”…”></a> 发送 Cookie
      预加载 <link rel=”prerender” href=”…”/> 发送 Cookie
      GET 表单 <form method=”GET” action=”…”> 发送 Cookie
      POST 表单 <form method=”POST” action=”…”> 不发送
      iframe <iframe src=”…”></iframe> 不发送
      ajax $.get(“…”) 不发送
      Image <img src=”…”> 不发送
    • None:不禁止第三方 Cookie,跨域请求浏览器都会发送cookie,当secure为true时,该值才有效(此条知识点以Chrome浏览器80版本之后为前提)

后端读写cookie

后端读取cookie的特点:

  • 后端通过request对象获取cookie:Cookie[] cookies = request.getCookies(),值得注意的是获取到的cookie数量为0时,该方法返回的是null而不是空数组。

设当前访问的地址URI为 /xxx/yyy,写入规则如下:

属性 后端写cookie的值 描述 浏览器实际存储的值 含义
name “abc” “abc”
name null null引用 后端抛IllegalArgumentException异常
name “”或” “ 空白字符串 后端抛IllegalArgumentException异常
name “ abc”或“abc ” 空白字符开头或结尾的字符串 后端抛IllegalArgumentException异常
value null null引用 “”
value “” 长度为0的字符串 “”
value “ “ 空白字符串 后端抛IllegalArgumentException异常
path /xxx 当前路径的或子路径 /xxx
path / / 代表根 ${contextPath} web容器上下文
path null null引用 ${contextPath} web容器上下文
path “”或” “ 长度为0或空白字符串 ${contextPath} web容器上下文
path xyz 不以斜杠开头的字符串 ${contextPath} web容器上下文
path /zzz 其它路径 /zzz
expires/max-age age > 0 过期时间大于0秒 age * 1000ms cookie到期销毁
expires/max-age age = 0 过期时间等于0秒 0ms cookie已经过期,销毁
expires/max-age age < 0 过期时间小于0秒 N/A(Session) 关闭浏览器时cookie销毁
  • 当${contextPath}web容器上下文为空时,则写入浏览器的path为 /。

前端读写cookie

代码可封装如下

1
2
3
4
5
6
7
8
9
10
11
12
13
function setCookie(name,value,age,path) {

var expiresString = "Session";
if (Number.isInteger(age)) {
// age 小于0则视为Session会话级别的cookie
if (age >= 0) {
var expires = new Date();
expires.setTime(expires.getTime() + age * 1000);
expiresString = expires.toGMTString();
}
}
document.cookie= name + "=" + value + "; expires=" + expiresString + ";path=" + path;
}

当前浏览器地址为 /xxx/yyy

属性 前端写cookie的值 浏览器实际存储的值 后端接受到的值 含义
name “abc” “abc” “abc”
name “”或” “ “” ${value} name无效,后端取出的name反而为其value值
name “ abc” “abc” “abc” 前端存cookie会处理name的首尾空白字符
name null “null” “null” null类型转换为”null”字符串
name undefined “undefined” “undefined” undefined类型转换为”undefined”字符串
value “abc” “abc” “abc”
value “” “” “”
value “ “ “” “” 前端存cookie会处理value的首尾空白字符
value null “null” “null” null类型转换为”null”字符串
value undefined “undefined” “undefined” undefined类型转换为”undefined”字符串
path /xxx /xxx null(后端不感知path值)
path /zzz /zzz null(后端不感知path值) 其它路径
path / / null(后端不感知path值) / 根
path xyz /xxx null(后端不感知path值) 当前路径的前一级路径,若不存在则为 /
path undefined /xxx null(后端不感知path值) 当前路径的前一级路径,若不存在则为 /
path null /xxx null(后端不感知path值) 当前路径的前一级路径,若不存在则为 /
path “” /xxx null(后端不感知path值) 当前路径的前一级路径,若不存在则为 /
path “ “ /xxx null(后端不感知path值) 当前路径的前一级路径,若不存在则为 /
expires “Session” N/A(Session) -1(后端不感知过期时间) 关闭浏览器时cookie销毁(存于内存)
expires t > 0 过期时间大于0秒 -1(后端不感知过期时间) cookie到期销毁(存于磁盘)
expires t < 0 过期时间小于0秒 -1(后端不感知过期时间) cookie已经过期,销毁
  • 前端js代码写cookie时,过对document.cookie赋值进行设置cookie
  • 设置的属性基本都有默认值,如果设置的值是“无理”的,属性都会取默认值,path属性默认为当前路径的前一级路径,expires属性默认为”Session”。
  • 设置的name和value属性会进行一定优化,需要主要后端取到实际值的不同

localStorage

localStorage属性在HTML5时增加,允许在浏览器中存储 key/value 对的数据,特点:

  • 只支持string类型的存储,key和value哪怕set时是number类型也会转成string类型
  • 遵循同源策略
  • 永久存在浏览器中,除非手动删除
  • 一般浏览器支持的是5M大小,不同的浏览器中会有所不同
  • 浏览器发送请求时不会带上

sessionStorage

sessionStorage属性在HTML5时增加,允许在浏览器中存储 key/value 对的数据,特点:

  • 只支持string类型的存储,key和value哪怕set时是number类型也会转成string类型
  • 数据仅在当前浏览器窗口有效
  • 一般浏览器支持的是5M大小,不同的浏览器中会有所不同
  • 浏览器发送请求时不会带上

小结

数据存放位置 非手动情况下数据销毁时机
session 服务端(依赖cookie存放sessionId) session过期
cookie 浏览器 到达过期时间
localStorage 浏览器 必须手动删除
sessionStorage 浏览器 浏览器窗口关闭