cookie

本文最后更新于:1 个月前

介绍cookie的属性、用途以及是如何发挥作用的

cookie

一、概述

Cookie 是服务器保存在浏览器的一小段文本信息,一般大小不能超过4KB。浏览器每次向服务器发出请求,就会自动附上这段信息。

主要用途:

  • 对话(session)管理:保存登录、购物车等需要记录的信息。
  • 个性化信息:保存用户的偏好,比如网页的字体大小、背景色等等。
  • 追踪用户:记录和分析用户行为。

包含的元数据:

  • Cookie 的名字
  • Cookie 的值(真正的数据写在这里面)
  • 到期时间(超过这个时间会失效)
  • 所属域名(默认为当前域名)
  • 生效的路径(默认为当前网址)

举例来说,用户访问网址www.example.com,服务器在浏览器写入一个 Cookie。这个 Cookie 的所属域名为www.example.com,生效路径为根路径/。如果 Cookie 的生效路径设为/forums,那么这个 Cookie 只有在访问www.example.com/forums及其子路径时才有效。以后,浏览器访问某个路径之前,就会找出对该域名和路径有效,并且还没有到期的 Cookie,一起发送给服务器。

如何获取当前网页cookie

如果浏览器打开了cookie功能的话,可以通过以下方式获取

1
document.cookie // "id=foo;key=bar"

如果需要知道浏览器是否打开cookie功能

1
window.navigator.cookieEnabled // true

两个网址只要域名相同,就可以共享 Cookie,不需要协议相同

二、cookie的用法

Cookie 由 HTTP 协议生成,也主要是供 HTTP 协议使用

cookie一般由服务器设置,设置方法是在HTTP响应头里,放置一个Set-Cookie字段(可以放置多个),它会在浏览器中保存一个名为foo的cookie

1
2
3
4
5
HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry
[page content]

除了设置cookie的值,还可以设置附加属性,如:

1
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly

修改已存在的cookie,需要满足四个条件:key、domain、path、secure值都必须相同,否则会新建一个cookie

浏览器向服务器发送 HTTP 请求时,会找出对该域名和路径有效,并且还没有到期的 Cookie,然后在请求头上携带上它。也就是说,把服务器早前保存在浏览器的这段信息,再发回服务器。

1
2
3
GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry

服务器收到浏览器发来的 Cookie 时,有两点是无法知道的。

  • Cookie 的各种属性,比如何时过期。
  • 哪个域名设置的 Cookie,到底是一级域名设的,还是某一个二级域名设的

什么情况下,cookie对当前域名和路径有效?

  • 默认情况,发送请求时,客户端只会携带属于当前域名(即“同源”,协议、域名、端口相同)的cookie。
  • 设置Path属性的情况,只会携带「当前域名」+「路径匹配」的cookie。举个例子:设置了Path=/docs的cookie,在发送域名/docs/list请求时,会被携带;但是发送域名/exec/list请求时,不会被携带。
  • 设置Domain属性的情况,向当前域名的子域名发送请求时,也会携带该cookie。举个例子:example.com设下的cookie,如果未设置Domain属性,向sub.example.com发送请求时,便不会带上这个cookie。

document.cookie属性用于读写当前网页的 Cookie

读取的时候,它会返回当前网页的所有 Cookie,前提是该 Cookie 不能有HTTPOnly属性。

三、cookie的属性

1、Expires、Max-Age

优先级:Max-Age > Expires

Expires属性指定一个具体的到期时间,到了指定时间以后,浏览器就不再保留这个 Cookie。它的值是 UTC 格式,可以使用Date.prototype.toUTCString()进行格式转换。

1
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;

Max-Age属性指定从现在开始 Cookie 存在的秒数,比如60 * 60 * 24 * 365(即一年)。过了这个时间以后,浏览器就不再保留这个 Cookie。

如果Set-Cookie字段没有指定ExpiresMax-Age属性(或者设置Expires为null),那么这个 Cookie 就是 Session Cookie,即它只在本次对话存在,一旦用户关闭浏览器,浏览器就不会再保留这个 Cookie。

2、Domain、Path

Domain属性指定浏览器发出 HTTP 请求时,哪些域名要附带这个 Cookie。如果没有指定该属性,浏览器会默认将其设为当前域名,这时子域名将不会附带这个 Cookie。比如,example.com不设置 Cookie 的domain属性,那么sub.example.com将不会附带这个 Cookie。如果指定了domain属性,那么子域名也会附带这个 Cookie。如果服务器指定的域名不属于当前域名,浏览器会拒绝这个 Cookie。

设置了Domain,子域名就会携带当前cookie;没有设置Domain,子域名就不会携带当前cookie

Path属性指定浏览器发出 HTTP 请求时,哪些路径要附带这个 Cookie。只要浏览器发现,Path属性是 HTTP 请求路径的开头一部分,就会在头信息里面带上这个 Cookie。比如,PATH属性是/,那么请求/docs路径也会包含该 Cookie。当然,前提是域名必须一致。

3、Secure、HttpOnly

Secure属性指定浏览器只有在加密协议 HTTPS 下,才能将这个 Cookie 发送到服务器。另一方面,如果当前协议是 HTTP,浏览器会自动忽略服务器发来的Secure属性。该属性只是一个开关,不需要指定值。如果通信是 HTTPS 协议,该开关自动打开。

Secure不需要手动设置

HttpOnly属性指定该 Cookie 无法通过 JavaScript 脚本拿到,主要是document.cookie属性、XMLHttpRequest对象和 Request API 都拿不到该属性。

4、SameSite

Chrome 51 开始,浏览器的 Cookie 新增加了一个SameSite属性,用来防止 CSRF 攻击和用户追踪。

Cookie 的SameSite属性用来限制第三方 Cookie,从而减少安全风险。它可以设置三个值:

  • Strict,完全禁止第三方 Cookie,换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。
  • Lax,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外
  • None,关闭SameSite属性,不过,前提是必须同时设置Secure属性

参考文章:浏览器模型 - Cookie - 《阮一峰 JavaScript 教程》 - 书栈网 · BookStack


cookie
http://timegogo.top/2022/10/05/HTTP/cookie/
作者
丘智聪
发布于
2022年10月5日
更新于
2024年2月2日
许可协议