定义

cookie一般是服务器保存在浏览器的一小段信息。
一般是用户登录后,服务器通过set-cookie响应头字段,在响应里返回一些cookie信息给浏览器。浏览器进行存储。下次浏览器再次发起http请求时,在满足一定条件下,浏览器会在请求中自动带上cookie。
注意:这个‘满足一定条件’,意味着浏览器不是任何情况下,都会携带cookie。这是根据 请求是否跨域、cookie的domain 和path字段综合考虑

cookie都有哪些属性

除了必备的key value外,还有以下比较重要的属性:

expires

指定一个具体的到期时间,时刻值。

Max-Age

指定从现在开始,这个cookie存在的秒数,时间段。
一旦超过这两个时间,浏览器会清除cookie。
如果同时指定expires和Max-Age,Max-Age会优先生效。
如果这两个属性都没有设置,这个cookie就只在当前会话(session)有效,一旦浏览器窗口关闭,就会被清除。

domain

指定当前网页发起请求时,什么域名可以携带这个cookie。

path

指定哪些路径可以携带这个cookie

httpOnly

如果设置了该属性为true,那么这个cookie无法通过js脚本获取到(主要是document.cookie、xmlhttprequest对象等),只能在请求中由浏览器自动携带给服务器。

跨域

浏览器的同源策略:
只有两个网页的协议+域名+端口号,完全相同,才是同源。

如果不同源,也就是从 a.example.com 向 b.example.com 发起请求,会有哪些限制呢?

  1. cookie、indexDB、localstorage 无法读取
  2. DOM 无法获得
  3. AJAX 请求不能发送

以上是正常情况下,两个不同源之间的限制行为。
这里重点说一下cookie:

1. 读cookie

通过js脚本 如document.cookie 获取当前网页的cookie,前提是cookie没有设置httpOnly属性。
再看cookie的domain属性,如果当前网页符合domain属性,就能读取。
‘符合’ 可以是完全相同: 如网页是a.example.com, 服务器下发并设置的cookie domain 也是 a.example.com,这个cookie就可以被获取到。

也可以是 网页是domain的下一级域名。 如设置domain为 .example.com,那就意味着所有以 .example.com 结尾的网页,都可以访问该cookie。比如a.example.com、b.a.example.com,这些都属于 .example.com的三级或四级域名。

如果是相反的情况,如 设置domain为 a.example.com,那 上一级域名 example.com 或完全非同源的 b.example.com,都无法获取到这个cookie

浏览器在请求里自动携带cookie

前边我们说过,服务器下发的cookie,浏览器在下一次请求时会带上。不过在跨域的情况下,根据cookie的domain设置,也有可能不会被带上。

下面只说跨域情况下,如 a.example.com 向 b.example.com 发起请求
首先有这个规则:

  • 跨域请求默认不携带cookie

跨域默认情况下的不携带,指的是不携带任何cookie,无论cookie的属性如何配置。
要想让浏览器携带,需要在前端发起请求时:

  • 如果是xmlhttprequest,设置 xhr.withCredentials = true; 官网
  • 如果是fetch api,设置credentials = 'include' 官网

两种意思都是允许跨域携带cookie
除了前端,服务器也需要一些配置,这里不做了解。

所以在进行了以上设置的前提下,再看cookie的domain
跨域请求携带的cookie是请求域名的cookie,而不是当前网页域名的cookie。
比如 a.example.com 向 b.example.com 发起请求,浏览器携带的是 domain 符合 b.example.com的cookie。

即,在当前网页同时存在以下几个同名cookie:
cookie1:domain = a.example.com
cookie2:domain = b.example.com
cookie3:domain = .example.com

那么携带的会是cookie2 3。2 不用说了,3会携带是因为 b.example.com是 .example.com的子域名。

总结:
跨域请求如何让浏览器携带cookie,主要是两点:

  1. 前端请求api里设置credentials
  2. 能带的cookie,必须是domain符合请求api的域名(不是当前网页域名)

S.D.
15 声望0 粉丝