浏览器中Cookie的全面介绍

news2024/11/27 14:50:58

简介

在Web前端开发时,我们经常会遇到一些浏览器存储相关的工具,例如Cookie。Cookie的英文本意是曲奇,但是在Web中,它被用作浏览器中存储的数据。Cookie都是name=value的结构,name和value都为字符串。

使用流程

  1. 在首次访问网站时,浏览器发送请求中并未携带Cookie。
  2. 浏览器看到请求中未携带Cookie,在HTTP的响应头中加入Set-Cookie
  3. 浏览器收到Set-Cookie后,会将Cookie保存下来
  4. 下次再访问该网站时,HTTP请求头就会携带Cookie。

下图分别为设置Cookie和携带Cookie的示例。

在这里插入图片描述
设置Cookie
在这里插入图片描述
携带Cookie

配置属性

在上面Set-Cookie的图中,我们可以看到,设置Cookie时,除了最前面的name和value之外,还配置了其他属性。实际上Cookie还有更多属性,可以查看浏览器的Application-Storage,获取当前网站的Cookie。
在这里插入图片描述

这里简单描述一下每个属性的含义:

属性含义
NameCookie的名称
Value对应名称的值
DomainCookie的域名
PathCookie生效的路径
Expires过期时间,过了这个时间后Cookie失效
Max-age生效时间,表示Cookie在多长时间后失效
SizeCookie的长度,为name和value的长度和
HttpOnly防止通过JavaScript访问Cookie
Secure只在HTTPS协议的情况下才会将Cookie传到后端
SameSite是否允许跨站请求时发送Cookie
Partitioned第三方Cookie分区
Priority优先级

下面我们对其中一些属性和作用进行讨论。

生命周期

Cookie是有生命周期的,在设置Cookie值时,可以同时设置有效期。当超过了这个有效期之后,Cookie便会失效,前端请求时,不会携带过期的Cookie。

Cookie的有效期有三种类型:

Session

这里的Session并不是存储在服务端的Session,而是指浏览器会话。如果Cookie的有效期为Session,一般关闭会话时,Cookie便会失效;而一些浏览器重启时,也会将会话恢复,此时Cookie并不会失效。

Expires

Expires表示过期时间,是一个确定的日期时间。例如Expires=Wed, 21 Oct 2015 07:28:00 GMT。当浏览器端本地的当前时间超过这个时间时,Cookie便会失效。

Max-age

Max-age表示Cookie的存活时间,以秒作为单位。例如Max-age=3000。当获取到该Cookie后开始倒计时,3000秒之后便失效。

注意:上述的生命周期都是服务端指定的。如果设置了Expires,则是把服务器时间和浏览器本地时间相比较,如果时间不同步,配置就会出现问题。而Max-age设置的是秒数,始终是浏览器本地时间自己相比较,不会出现时间不同步的问题。

作用范围

作用范围主要由Domain和Path两个属性来控制。

Domain

Domain用来设置Cookie作用的域名,即Cookie在哪个网站生效。默认情况下,生效的域名为当前访问的域名。例如我们在jzplp.com设置的Cookie,就只能限制该网站内使用。

多级域名

如果访问的网站有多级域名,则Cookie默认仅在访问的多级域名内生效。如果希望在更大范围内生效,可以指定域名。

例如我们在a.jzplp.com下设置的Cookie,就只在这个域名下生效。但是如果我们在设置cookie时同时设置了domain=jzplp.com,则该Cookie可以在jzplp.com下的任何域名内生效。比如:

  • jzplp.com
  • a.jzplp.com
  • b.jzplp.com
  • c.d.jzplp.com

Path

有时候,我们希望Cookie仅仅在部分路径下生效,就可以使用Path进行限制。这里的路径就是网站的路由。默认的path=/,即在所有路径下生效。
如果设置了path=/abc,则只在/abc路径下生效。比如:

  • jzplp.com 不生效
  • jzplp.com/abc 生效
  • jzplp.com/abc/def 生效
  • jzplp.com/qaz 不生效
  • jzplp.com/qaz/abc 不生效

个数和大小限制

限制规则

不同的浏览器允许的Cookie大小并不相同,通常的限制为:

  • 个数限制: 20~50
  • 总大小限制: 4KB左右

网络上也有人整理各种浏览器详细的限制。

IE6.0IE7.0/8.0OperaFirefoxSafariChrome
cookie个数每个域为20个每个域为50个每个域为30个每个域为50个没有个数限制每个域为53个
cookie大小4095个字节4095个字节4096个字节4097个字节4097个字节4097个字节

来源:Cookie个数限制及大小

一个Cookie的大小可以在浏览器中查看Size属性得知,这个大小是key和value的和。

Priority优先级

当Cookie的数量超过限制时,路蓝旗会清除一部分Cookie。清除哪些合适呢?Priority属性用来定义Cookie的优先级,低优先级的Cookie会优先被清除。

Priority属性有三种: Low, Medium, High

HttpOnly

通常的Cookie在客户端(一般指浏览器)是可以通过脚本代码(一般指js)访问的。方式可见JavaScript中操作Cookie。

如果设置了HttpOnly属性,则该Cookie在浏览器中无法通过js代码访问,经过我测试也无法写入。这样可以防止窃取Cookie信息,一般用来防止XSS攻击。

跨站与Samesite设置

Samesite是Cookie的跨站属性,也可以看做是“更高级”的作用范围设置。部分内容参考了几篇文章:SameSite Cookie,防止CSRF攻击, Cookie 的 SameSite 属性

跨站与跨域

一般浏览器限制请求的内容是按照跨域来判断的,比如XHR和fetch。但是Samesite限制的并不是跨域,而是跨站。跨站是比跨域更宽松的一种限制。可以这么说如果跨站,那么肯定会跨域,但如果跨域,那么不一定会跨站。

跨站和跨域的主要区别

  • 子域名不同时 属于跨域 不属于跨站
    例如 a.jzplp.comb.jzplp.com
  • 端口不同时 属于跨域 不属于跨站
    例如 jzplp.com:8000jzplp.com:9000
  • IP不同时(如果直接使用IP访问网站) 属于跨域 属于跨站

Public Suffix List

在上面子域名的的跨站说明中,是存在漏洞的。我们假设这样的情况:

  1. a.jzplp.comb.jzplp.com 实际属于同站
  2. jzplp.com.cnother.com.cn 实际属于跨站
  3. jzplp.github.ioother.github.io 实际属于跨站

可以看到,上面的三个域名格式是相同的,都使用了两个点来分隔。
第一个属于同站。看第二个例子,com.cn是我们国家颁布的二级域名并不是指的某一个网站。显然这种域名后缀,并不能认为是同站。除了我国,还有其他国家和组织也会公布这种二级甚至更高级的域名。再看第三个例子,是Github提供的网站域名。使用github.io后缀的网站,显然也不能认为是同站。

因此,仅仅通过网址格式匹配,是无法判断是否同站的。因此,浏览器会维护一个列表:Public Suffix List。列表里面记录了这些需要特殊匹配的域名后缀,比如上面提到的com.cngithub.io等等,这个叫做有效顶级域名,eTLD。在遇到一个域名时,会首先匹配列表中的后缀,再把eTLD+1个字段相同表示为同站,不同表示为非同站。

例如 列表中的域名后缀为com.cn,那么eTLD+1个字段表示为jzplp.com.cn。那么a.jzplp.com.cnb.jzplp.com.cn属于同站, jzplp.com.cnother.com.cn属于跨站。

Public Suffix List列表的内容,这个列表会随着浏览器的更新而更新。

Public Suffix List除了应用在Samesite中,还在其他地方有应用。例如Cookie中的Domain也使用了这里eTLD+1个字段作为设置的最大范围。

请求分类

当我们在浏览器中访问一个网站,在输入一个网址后,首先返回的是一个HTML页面。而在这个页面中还可以继续包含其他请求,比如图片,iframe,fetch等等。这些请求可以被分为两类:

  1. 可能打开新页面或者改变当前页面的请求。
    例如: window.open()<a>链接,form表单提交等。
  2. 不改变当前页面的请求。
    例如: <script><css><img>等标签,fetch,XHR请求等。

可以看到,这两类的主要区别是:第一类请求直接把页面替换了,或者打开了一个新的页面,即——和原有的页面不属于同一个页面。而第二类请求依然在原页面上,仅仅是做一些内容上的更新。这个请求分类与Samesite配置相关。

Samesite设置

上面跨站,eTLD和请求分类,是理解Samesite设置的基础。Samesite设置有三种:

  1. None
    关闭SameSite属性,即不对跨站Cookie做限制。关闭的前提是设置了Secure,即Cookie只能在HTTPS下使用,否则关闭是无效的。
  2. Strict
    禁止发送跨站Cookie。即不管是什么请求,如果我们请求的地址与所在的页面地址属于跨站,那么Strict的Cookie将不会被发送。
  3. Lax 默认设置
    在部分情况下可以发送跨站Cookie:请求分类的第1种,即可能打开新页面或者改变当前页面的请求,而且是个Get请求时,可以发送。其他请求不允许发送。
  • Strict的设置非常严格,在部分场景下会影响用户正常使用。例如(假想场景)我们在一个网站中提供了Github网站链接;其他用户点击后,由于Strict设置,Cookie不会发送,因此点击链接后是未登录状态。
  • Lax设置基本保证了不会产生CSRF攻击,但是如果需要部分请求跨站的场景,又会造成限制。

Partitioned独立分区

上面我们介绍过的SameSite属性,是为限制第三方Cookie进行跨站传输而设置的。但是在很多场景下,SameSite属性并不够用,我们需要“更更高级”的作用范围设置。这就是Partitioned属性————Cookie分区设置,也叫作CHIPS。关于提案和讨论可以查看GitHub-CHIPS

SameSite属性仅仅能控制网站是否发送第三方Cookie,但是不能针对不同的网站来源做出不同的Cookie反应。例如一个网站对于外部的网站需要记录不同的第三方Cookie。Partitioned属性允许在请求第三方cookie,即跨站传输Cookie后,浏览器设置一个分区Key(PartitionKey),标明当前访问的网站来源。后续浏览器再次请求第三方Cookie时,浏览器会判当前网站的域名与分区Key是否一致。如果一致才发送这个Cookie,如果不一致则不发送。

在这里插入图片描述

假设C网站开启了分区Cookie设置,例如Set-Cookie: value=1; Partitioned;。有A网站和B网站分别都会调用C网站的接口。

  1. A网站第一次访问后,浏览器除了记录Cookie,还会记录下PartitionKey=A网站。
  2. 当我们访问B网站时,也会请求C网站的接口。浏览器使用PartitionKey判断,此时访问的网站与A网站不是同一个,不会发送PartitionKey=A网站的Cookie。
  3. 我们访问B网站的C接口后,浏览器除了记录Cookie,还会记录下PartitionKey=B网站。
  4. 我们再一次访问A网站或者B网站,浏览器会对应的传输PartitionKey的值为对应网站的Cookie。

这样,就实现了对第三方Cookie更细粒度的访问控制。

除了独立分区之外,浏览器还在讨论其他关于第三方Cookie作用范围设置的方法,例如SameParty属性等等。可以看下:详解Cookie新增的SameParty属性

JavaScript中操作Cookie

在浏览器中使用js,可以直接设置Cookie。一次只能设置一个Cookie。但是可以同时对单个Cookie的属性进行设置,每个属性使用分隔符;。

设置

document.cookie = "a=1;";
document.cookie = "a=1; doamin=jzplp.com";
document.cookie = "a=1; doamin=jzplp.com;path=/abc";

修改某个Cookie,相当于对其进行重新设置。

读取

document.cookie

读取到的是一个字符串,内容为该页面的所有Cookie,不同的Cookie用分隔符;分隔。只能读到key和value,其余的属性读不到。例如:

"a=1; b=2"

删除

js中没有直接删除Cookie的方法。如果需要删除某个Cookie,需要重新设置该Cookie,将它的有效期直接设置为过期,即可实现删除功能。例如:

document.cookie = "a=1; max-age=-1";

参考

  • MDN Cookies
    https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies
  • MDN Set-Cookie
    https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Set-Cookie
  • [译]Cookies Having Independent Partitioned State (CHIPS)
    https://juejin.cn/post/7086386576837574693
  • wikipedia Cookie
    https://zh.wikipedia.org/wiki/Cookie
  • Cookie个数限制及大小
    https://my.oschina.net/gaollg/blog/71299
  • 在什么情况下JavaScript写入cookie的操作会失败?
    https://www.zhihu.com/question/20332255
  • SameSite Cookie,防止CSRF攻击
    https://www.cnblogs.com/ziyunfei/p/5637945.html
  • Public Suffix List 列表
    https://publicsuffix.org/list/public_suffix_list.dat
  • Cookie 的 SameSite 属性
    http://www.ruanyifeng.com/blog/2019/09/cookie-samesite.html
  • Cookie独立分区 CHIPS
    https://github.com/privacycg/CHIPS
  • 谁能帮我们顺利过渡到没有三方 Cookie 的未来?(CHIPS)
    https://mp.weixin.qq.com/s/sw0lWmUdBSmypMjIg8ulvA
  • 详解Cookie新增的SameParty属性
    https://mp.weixin.qq.com/s/GFQo-GnU-ROc6wmbCQp3Nw
  • 在什么情况下 JavaScript 写入 cookie 的操作会失败?
    https://www.zhihu.com/question/20332255

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/759776.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023.7.16-求平方

功能&#xff1a;输入一个整数&#xff0c;显示出不大于这个整数的所有整数的平方。 程序&#xff1a; #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int main() {int a0, b;printf("请输入一个整数&#xff1a;");scanf("%d",&a);pr…

Go语言之重要数组类型数组

我们之前学习过变量&#xff0c;当存储一个学生名字时可以name“jack”,但是如果班级有三十人&#xff0c;每个人的名字都想存储到内存中怎么办呢&#xff1f;总不能用三十个变量分别存储吧&#xff0c;这时数组就可以发挥作用了。 数组其实是和字符串一样的序列类型&#xff0…

深入了解加快网站加载时间的 JavaScript 优化技术

目录 01、最小化文件大小 01&#xff09;、JavaScript 代码示例&#xff1a;缩小前后 02、文件压缩 01&#xff09;、Gzip 和 Brotli 压缩方法 02&#xff09;、压缩的服务器端配置 03、捆绑以减少网络请求 01&#xff09;、捆绑说明 02&#xff09;、捆绑工具 03&…

OWASP常见Web安全漏洞

OWASP&常见Web安全漏洞 一、OWASP介绍二、OWASPTOP10与常见漏洞讲解2.1、OWASP Top10 2013 VS 20172.2、OWASP Top10 20212.3、A1&#xff1a;2017 注入2.3.1、SQL注入攻击2.3.2、命令注入攻击 2.4、A2&#xff1a;2017失效的身份认证&#xff08;业务逻辑漏洞&#xff09;…

Linux——动静态库的制作和使用超详细(实操+代码+原理介绍)

动静态库的制作和使用 1️⃣.动静态库介绍&#x1f3c0;静态库⚽️动态库&#x1f3c8;区别&#x1f3d0;使用动态库的优点包括&#xff1a;&#x1f3c9; 使用静态库的优点包括&#xff1a; 2️⃣静态库的制作&#x1f34a;Q:库文件能不能有main()函数&#xff1f;&#x1f34…

clickhouse基础数据类型 语法及使用可视化数据库工具 DBeaver

新建一个名为 test 的数据库&#xff1a;右击数据库点击新增&#xff0c;然后创建一张 test &#xff0c;utf8mb4 字符的&#xff0c;点击确定 在 test 数据库下新建一张数据表&#xff0c;如下所示&#xff1a;右击表&#xff0c;然后点击新建表 鼠标放列上面&#xff0c;右键…

b站视频播放三倍速

目录 一、操作 一、操作 document.querySelector(video).playbackRate 31、F12或者在当前界面鼠标右击选择检查 打开开发者工具平台 2、在console界面执行document.querySelector(video).playbackRate 3 document.querySelector(video).playbackRate 3

vector模拟实现

目录 vector相关接口实现 使用memcpy拷贝问题 迭代器失效 引起失效的操作 指定位置元素的删除操作 ​编辑引起底层空间改变的操作 vector相关接口实现 template<typename T> class vector { public:typedef T* iterator;typedef const T* const_iterator; public:…

基于MSP432P401R跟随小车(一)【2022年电赛】

文章目录 一、赛前准备1. 硬件清单2. 工程环境 二、赛题思考三、软件设计1. 路程、时间、速度计算2. 距离测量3. 双机通信4. 红外循迹 四、技术交流 一、赛前准备 1. 硬件清单 主控板&#xff1a; MSP432P401R测距模块&#xff1a; GY56数据显示&#xff1a; OLED电机&#x…

MinUv2靶场详解

MinUv2靶场详解 这个靶场我学到了.bash_history文件&#xff0c;每个用户都有一个名为 .bash_history 的文件&#xff0c;它位于用户的主目录中&#xff0c;默认有500行最近执行的命令。 这个靶场我用vmware是不能打开的&#xff0c;用virtualBox就可以&#xff0c;并且打开时…

MySQL索引、事务

目录 索引 作用 查看索引 创建索引 删除索引 索引背后的数据结构 B树 B树 事务 事务的本质 事务的特性 并发执行事务产生的问题 脏读问题 不可重复读 幻读 MySQL中隔离级别 read uncommitted readcommitted repeatable read serializable 索引 索引的本质…

SolidUI AI生成可视化,0.1.0版本模块划分以及源码讲解

1.背景 随着文本生成图像的语言模型兴起&#xff0c;SolidUI想帮人们快速构建可视化工具&#xff0c;可视化内容包括2D,3D,3D场景&#xff0c;从而快速构三维数据演示场景。SolidUI 是一个创新的项目&#xff0c;旨在将自然语言处理&#xff08;NLP&#xff09;与计算机图形学相…

【Java虚拟机学习1】JVM运行时数据区

JVM运行时数据区 一、前言 我们知道Java程序是运行在JVM&#xff08;Java虚拟机&#xff09;上的&#xff0c;Java程序运行时会占用一定的内存&#xff0c;在虚拟机自动管理机制的帮助下&#xff0c;不再需要为每一个new操作去写配对的delete/free代码&#xff0c;不容易出现…

指针进阶详解(下)

指针进阶详解&#xff08;下&#xff09; 前言1. 函数指针1.1 两端有趣代码 2. 函数指针数组2.1 函数指针数组的用途之一&#xff1a;转移表 3. 指向函数指针数组的指针4. 回调函数5. 结尾 前言 在指针进阶详解&#xff08;上&#xff09;中&#xff0c;我们已经介绍了部分指针…

基于数据安全的风险评估(三):风险分析与评估

完成了资产识别、脆弱性识别及威胁识别后&#xff0c;我们可以采用适当的方法和工具确定威胁利用脆弱性导致安全事件发生的可能性。综合安全事件作用资产价值及脆弱性的严重程度&#xff0c;判断事件造成的损失及对组织的影响&#xff0c;即安全风险。 一 风险计算形式及关键环…

HTTP协议对比HTTPS协议

HTTP协议对比HTTPS协议 1. HTTP协议1.1 概述1.2 HTTP协议格式1.3 HTTP协议支持的方法1.3.1 GET方法1.3.2 POST方法1.3.3 其他HTTP方法1.3.4 GET对比POST 1.4 请求报文1.4.1 Content-Type&#xff1a;请求体中数据格式1.4.2 Cookie&#xff1a;浏览器缓存 1.5 响应报文1.5.1 状态…

LED驱动(原始架构优化:分层/分离)——STM32MP157

文章目录 优化思想&#xff1a;分层Demo的LED驱动程序led_opr.hboard_demo.cleddrv.cledtest.cMakefile编译测试 STM32MP157的LED驱动程序board_stm32mp157.cleddrv.cled_opr.hMakefiel编译测试 优化思想&#xff1a;分离Demo的LED驱动程序led_resource.hboard_A_led.cchip_dem…

MacOS系统(M1/M2)安装AI绘画StableDiffusion保姆级教程

TOC 安装完成后&#xff0c;推荐阅读这篇教程&#xff1a;AI绘画&#xff1a;Stable Diffusion 终极炼丹宝典&#xff1a;从入门到精通 实操环境&#xff1a; macOS 13 Arm64&#xff08;建议12以上的系统使用&#xff09; Apple M1 先来看几个样例&#xff1a; AI绘画S…

goland自定义代码模版

在 GoLand 中我们既可以修改已有代码模版&#xff0c;也可以新建属于我们自己的代码模版&#xff0c;按需配置。 一、修改已有代码模版 现在代码编辑页输入你想更改的代码模版&#xff0c;然后点击右下角的小灯泡按钮&#xff0c;接着选中编辑活动模版设置即可。 二、新建…

[机缘参悟-99] :关于局部最优与全局最优解的人生感悟

在没有获取全局信息之前&#xff0c;要获得全局最优解几乎是不可能的&#xff0c;最多是概率大一点而已&#xff0c;大多数时候&#xff0c;由于时空资源的限制&#xff0c;获得往往是局部最优解&#xff0c;局部最优解&#xff0c;放在全局&#xff0c;往往并非全局最优&#…