上图是Chrome浏览器中的Cookie截图,cookie的属性:Name、Value、Domain、Path、Expires/Max-age、Size、HttpOnly、Secure、SameSite、SameParty、Priority。下面依次介绍这些属性。
Name是Cookie的名称,Cookie一旦创建,名称便不可更改,一般名称不区分大小写。
Value是cookie名称Name对应的Cookie的值,如果值为Unicode字符,需要为字符编码。如果值为二进制数据,则需要使用BASE64编码。
指定Cookie的有效域,决定在向该域发送请求时是否携带此Cookie。Domain属性的默认值是创建cookie的网页所在服务器的主机名。不能将一个cookie的域设置成服务器所在的域之外的域。Domain的设置是对子域生效的,如Doamin设置为 .a.com,则b.a.com和c.a.com均可使用该Cookie,但如果设置为b.a.com,则c.a.com不可使用该Cookie。
注意:在RFC2109规范,没有前导点的域意味着不能在子域上使用它,而只有一个前导点(.a.com)允许跨子域使用。然而,现代浏览器尊重更新的规范RFC6265,并将忽略任何前导点,这意味着您可以在子域和顶级域上使用cookie。如果你设置了一个cookie的Domain为a.com,那么b.a.com、c.a.com都可以使用该cookie。
在tomcat8.5版本后Domain规则:
Tomcat更换默认的 CookieProcessor 实现为 Rfc6265CookieProcessor ,之前的实现为 LegacyCookieProcessor 。
LegacyCookieProcessor 主要是实现了标准RFC6265, RFC2109 和 RFC2616,而Rfc6265CookieProcessor是实现了标准RFC6265。
Rfc6265CookieProcessor拼接Domain时增加了对domain 的校验(Rfc6265CookieProcessor类的validateDomain(String domain)方法),即必须以数字或者字母开头,必须以数字或者字母结尾,不支持Domain以.开头。
如果一定要支持设置.开头的Domain,有一下几种方式:
直接修改Tomcat安装目录下的conf\context.xml文件,指定cookie处理器为 org.apache.tomcat.util.http.LegacyCookieProcessor
<Context>
<CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor" />
</Context>
如果使用的是SpringBoot,直接指定容器中的cookie处理器。
@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> cookieProcessorCustomizer() {
return (factory) -> factory.addContextCustomizers((context) ->
context.setCookieProcessor(new LegacyCookieProcessor()));
}
domain对浏览器写入cookie的影响(例如当前域为a.test.com):
传入domain值 | 写入结果 | 写入domain值 |
---|---|---|
空 | 成功 | a.test.com |
a.test.com | 成功 | .a.test.com |
.a.test.com | 成功 | .a.test.com |
b.test.com | 失败 | |
.b.test.com | 失败 | |
test.com | 成功 | .test.com |
.test.com | 成功 | .test.com |
www.test.com | 失败 | |
www.qq.com | 失败 |
归纳总结:
其他注意事项:
指定Cookie的有效路径,和Domain类似,也对子路径生效,如Cookie1和Cookie2的Domain均为a.com,但Path不同,Cookie1的Path为 /b/,而Cookie的Path为 /b/c/,则在a.com/b页面时只可以访问Cookie1,在a.com/b/c页面时,可访问Cookie1和Cookie2。Path属性需要使用符号“/”结尾。
Expires和Max-age均为Cookie的有效期.
Expires:HTTP/1.0中定义,Cookie过期的绝对时间(GMT格式)。若设置为以前的时间,则该Cookie立刻被删除,若不设置则默认页面关闭时删除该Cookie。
Expires = 当时服务器的时间+有效时间
Max-age:HTTP/1.1中定义,Cookie存活的相对时间(单位秒,如:3600),表示多少秒之后失效。若Max-age设置为0,则立刻失效,设置为负数,则在页面关闭时失效。Max-age默认为 -1。
如果max-age为0,则表示删除该cookie。cookie机制没有提供删除cookie的方法,因此通过设置该cookie即时失效实现删除。
HTTP/1.1后使用Max-age来替换Expires,但为了向下兼容,一般Expires、Max-age会同时存在。
Expires的缺点:返回的到期时间是服务端的时间,如果客户端的时间与服务端的时间相差很大,那么误差就很大。例如:
Size是此Cookie的大小。在所有浏览器中,任何cookie大小超过限制都被忽略,且永远不会被设置。各个浏览器对Cookie的最大值和最大数目有不同的限制。
浏览器 | Cookie最大条数 | Cookie最大长度(单位:字节) |
---|---|---|
IE | 50 | 4095 |
Chrome | 150 | 4096 |
FireFox | 50 | 4097 |
Opera | 30 | 4096 |
Safari | 无限制 | 4097 |
用于避免cookie被Javascript访问,值为 true 或 false,默认false。若设置为true,则不允许通过脚本document.cookie去更改这个值,同样这个值在document.cookie中也不可见,但在发送请求时依旧会携带此Cookie。
Cookie的安全属性,用于指定cookie需要通过安全Socket层连接传递。值为 true 或 false,默认值false,若设置为true,则浏览器只会在HTTPS和SSL等安全协议中传输此Cookie,不会在不安全的HTTP协议中传输此Cookie。
优先级,chrome的提案,定义了三种优先级,Low/Medium/High,当cookie数量超出时,低优先级的cookie会被优先清除。
在3其他浏览器中,不一定存在Priority属性。
SameSite用来限制第三方 Cookie,从而减少安全风险。它有3个属性,分别是:
暂无
浏览器将cookie信息以name=value对的形式存储于本地,每当请求新文档时,浏览器将发送Cookie,目的是让Server可以通过HTTP请求追踪客户。所以从WEB性能的角度来说我们要尽量的减小cookie,以达到传输性能的最大化。
浏览器对于Web服务器应答包头中Cookie的操作步骤:
浏览器对Web服务器请求包头中所有的Cookie进行筛选的步骤:
cookie的名/值中的值不允许包含分号,逗号和空格符,为了最大化用户代理和服务器的兼容性,任何被存储为 cookie 值的数据都应该被编码,例如用我们前端熟知的js全局函数encodeURIComponent编码和decodeURIComponent解码。
每次新的请求,浏览器都会发送Cookie到服务器,导致WEB性能下降。所以不建议将cookie作为客户端存储一种实现方案。
cookie机制没有提供删除cookie的方法,因此通过设置该cookie即时失效实现删除。
max-age为0,或者Expires为一个已过期时间,则表示删除该cookie。
常见cookie删除无效问题:
一般是因为删除时指定的name、domain、path这三个参数的值与需要删除的cookie这三个参数的值有不同。