共计 5068 个字符,预计需要花费 13 分钟才能阅读完成。
欢送关注公众号【码上出击】
,更多精彩内容敬请关注公众号最新消息。
cookie 是一个前端工程师每天都在打交道的内容,因而简直所有的前端面试都会问到 cookie 的相干常识。本文将与前端无关的 cookie 常识整顿成 18 个问题,笼罩了所有面试状况。
前世今生:Cookie 和 Session 体系
咱们晓得,HTTP 是一种无状态协定,无状态是指服务端对于客户端每次发送的申请都认为它是一个新的申请,上一次会话和下一次会话没有分割。
然而,很多场景下,咱们须要晓得下一次的会话和上一次的会话的关系(比方登陆之后咱们须要记住登陆状态),这个时候就引入了 Cookie 和 Session 体系。
Cookie: 客户端申请服务器时,如果服务器须要记录该用户状态,就通过 response Headers 向客户端浏览器颁发一个 Cookie,而客户端浏览器会把 Cookie 保存起来。当浏览器再申请服务器时,浏览器把申请的网址连同该 Cookie 一起提交给服务器。服务器通过查看该 Cookie 来获取用户状态。
Session: 当服务器接管到申请时,就从存储在服务器上的有数 session 信息中去查找客户端申请时带过去的 cookie 的状态。如果服务器中没有这条 session 信息则增加一条 session 信息。
通常 Cookie 中存的是 session 信息通过计算后的惟一 Id(sessionId)。
cookie 的 18 个问题
1. cookie 存储在哪里?
cookie 个别是被浏览器以 txt 的模式存储在电脑硬盘中,供该浏览器进行读、写操作。
2. cookie 是如何工作的?
- request
当浏览器发动一个申请时,浏览器会主动查看是否有相应的 cookie,如果有则将 cookie 增加到 Request Headers 的 Cookie 字段中(cookie 字段是很多 name=value 以分号分隔的字符串)。
- response
当服务端须要种 cookie 时,在 http 申请的 Response Headers 中增加 Set-Cookie 字段,浏览器接管到之后会主动解析辨认,将 cookie 种下。
3. cookie 和 session 的区别?
- 存储地位不同:cookie 数据寄存在客户的浏览器上,session 数据放在服务器上。
- 存储大小不同:个别单个 cookie 保留的数据不能超过 4k, 单个域名最多保留 30 个 cookie(不同浏览器有差别);session 则无大小和数量限度。
4. 什么是 session 级别的 cookie?
session 级别的 cookie 只针对以后会话存在,会话终止则 cookie 隐没。
当 cookie 没有设置 expires 的时候,该 cookie 只会在网页会话期间存在,当浏览器退出的时候,该 cookie 就会隐没。
浏览器中的体现为 Expires/Max-Age 的内容为 Session。
5. cookie 能够被谁来操作?
服务端和 js 都能够读 / 写 cookie。
6. cookie 各属性详解
- Name: cookie 名
- Value: cookie 值。
- Domain: cookie 的域名。如果设成.example.com,那么子域名 a.example.com 和 b.example.com,都能够应用.example.com 的 cookie; 反之则不能够。
- Path: 容许读取 cookie 的 url 门路,个别设置为 /。
- Expires:cookie 过期工夫。不设置,则为 Session 会话期,页面退出时 cookie 生效。
- HttpOnly: 设置为 true 时,只有 http 能读取。js 只能读取未设置 HttpOnly 的 cookie。
- Secure: 标记为 Secure 的 cookie,只有 https 的申请能够携带。
-
SameSite: 限度第三方 url 是否能够携带 cookie。有 3 个值:Strict/Lax(默认)/None。(chrome51 新增属性,chrome80+ 强制执行)
- Strict: 仅容许发送同站点申请的的 cookie
- Lax: 容许局部第三方申请携带 cookie,即导航到指标网址的 get 申请。包含超链接,预加载 <link rel=”prerender” /> 和 get 表单 <form method=”GET” /> 三种模式发送 cookie
- None: 任意发送 cookie,设置为 None,(须要同时设置 Secure,也就是说网站必须采纳 https)
- Priority:优先级,chrome 的提案(firefox 不反对),定义了三种优先级,Low/Medium/High,当 cookie 数量超出时,低优先级的 cookie 会被优先革除。
7. js 和服务端对 cookie 的操作有什么不同?
cookie 有一个属性是 HttpOnly,HttpOnly 被设置时,表明该 cookie 只能被 http 申请读取,不能被 js 读取,具体的体现是:document.cookie 读取到的内容不蕴含设置了 HttpOnly 的 cookie。
8. js 如何操作 cookie
js 操作读 / 写 cookie 的 api 是document.cookie,。
- 读 cookie
document.cookie。
console.log(document.cookie);
// cna=8fDUF573wEQCAWoLI8izIL6X; xlly_s=1; t=4a2bcb7ef27d32dad6872f9124694e19; _tb_token_=e3e11308ee6fe; hng=CN%7Czh-CN%7CCNY%7C156; thw=cn; v=0;
读取后的 cookie 是一个字符串,蕴含了所有 cookie 的 name 和 value(用分号分隔),须要咱们自行将 cookie 解析进去。
- 写 cookie
document.cookie = 'uid=123;expires=Mon Jan 04 2022 17:42:40 GMT;path=/;secure;'
document.cookie = 'uid=123;expires=Mon Jan 04 2022 17:42:40 GMT;path=/caikuai;domain=edu.360.cn;secure;samesite=lax'
一次只能写一个 cookie,想要写多个 cookie 须要操作屡次。
1. expires 默认为 session 级别。2. path 默认为以后 url 的门路。3. domain 默认为以后拜访域名。4. samesite 默认为 Lax。5. secure 默认为 false(即 http)。
- 删除 cookie
只须要将一个曾经存在的 cookie 名字过期工夫设置为过来的工夫即可。
document.cookie = 'uid=dkfywqkrhkwehf23;expires=' + new Date(0) + ';path=/;secure;'
- 批改 cookie
从新赋值就好,旧值会笼罩新值。
留神:须要保障 path 和 domain 这两个值不变,否则会增加一个新的 cookie。
Q:如果要设置多个 cookie 怎么办?<br/>
A:document.cookie 一次只能设置一个 cookie,须要操作屡次 document.cookie。
9. 服务端如何读写 cookie
第 2 节“cookie 是如何工作的”通知咱们,服务端是能够读和写 cookie 的,从图中咱们能够看到,写 cookie 时,一条 Set-Cookie 写入一条 cookie。读 cookie 时,所有的 cookie 信息都被放进了 cookie 字段中。
以 express 应用为例:
- 写 cookie
res.setHeader('Set-Cookie', ['uid=123;maxAge: 900000; httpOnly: true']);
// 或者
res.cookie("uid",'123',{maxAge: 900000, httpOnly: true});
- 读取 cookie
console.log(req.getHeader('Cookie')); // 拿到所有 cookie
// 或者
console.log(req.cookie.name);
10. Cookie 大小和数量的限度
不同的浏览器对 Cookie 的大小和数量的限度不一样,个别,单个域名下设置的 Cookie 不应超过 30 个,且每个 Cookie 的大小不应超过 4kb,超过当前,Cookie 将会被疏忽,不会被设置。
11. 查看浏览器是否关上 Cookie 性能
window.navigator.cookieEnabled // true
12. cookie 的共享策略是什么
domain 和 path 独特决定了 cookie 能够被哪些 url 拜访。
拜访一个 url 时,如果 url 的 host 与 domain 统一或者是 domain 的子域名,并且 url 的门路与 path 局部匹配,那么 cookie 才能够被读取。
如果 cookie 如上图所示,那么一个 url 与可读取的 cookie 对应关系为:
url | uid1 | uid2 | uid3 |
---|---|---|---|
https://edu.360.cn/caikuai/ | √ | √ | √ |
https://edu.360.cn/ | √ | √ | × |
https://360.cn/article/123.html | × | √ | × |
13. 跨域申请(CORS)中的 cookie
首先 cookie 的 SameSite 须要设置为 None。
其次对于将 Access-Control-Allow-Credentials 设置为 true 的接口(示意容许发送 cookie),须要咱们在发送 ajax 申请时,将 withCredentials 属性设为 true。
14. cookie 的编码
document.cookie = 'uid=123;expires=Mon Jan 04 2022 17:42:40 GMT;path=/caikuai;domain=edu.360.cn;secure;samesite=lax'
从 document.cookie 的赋值中咱们能够看到,存在 等于号、冒号、分号、空格、逗号、斜杠 等特殊字符,因而当 cookie 的 key 和 value 中存在这几种符号时,须要对其进行编码,个别会用 encodeURIComponent/decodeURIComponent 进行操作。
Q: 为什么不应用 escape 和 encodeURI 进行编码呢?<br/>
A: 因为相比这两个 api,encodeURIComponent 能够将更多的字符进行编码,比方 ”/”。
15. cookie 与 web 平安
1. cookie 如何应答 XSS 破绽 *
XSS 破绽的原理是,因为未对用户提交的表单数据或者 url 参数等数据做解决就显示在了页面上,导致用户提交的内容在页面上被做为 html 解析执行。
惯例计划:对特殊字符进行解决,如 ”<“ 和 ”>” 等进行本义。
cookie 的应答计划:对于用户利用 script 脚本来采集 cookie 信息,咱们能够将重要的 cookie 信息设置为 HttpOnly 来防止 cookie 被 js 采集。
2. cookie 如何应答 CSRF 攻打
CSRF,中文名叫跨站申请伪造,原理是,用户登陆了 A 网站,而后因为某些起因拜访了 B 网站(比方跳转等),B 网站间接发送一个 A 网站的申请进行一些危险操作,因为 A 网站处于登陆状态,就产生了 CSRF 攻打(外围就是利用了 cookie 信息能够被跨站携带)!
惯例计划:采纳验证码或 token 等。
cookie 的应答计划:因为 CSRF 攻打外围就是利用了 cookie 信息能够被跨站携带,那么咱们能够对外围 cookie 的 SameSite 设置为 Strict 或 Lax 来防止。
16. 不同的浏览器共享 cookie 吗?
不同的浏览器相互不通信,彼此是独立的 cookie。因而,咱们在一个浏览器上登陆了某个网站,换到另一个浏览器上的时候须要从新登陆。
17. cookie 和 localStorage/sessionStorage 的差别
个性 | Cookie | localStorage | sessionStorage |
---|---|---|---|
操作者 | 服务器和 js | js | js |
数据的生命期 | 可设置生效工夫 | 除非被革除,否则永恒保留 | 仅在以后会话下无效,敞开页面或浏览器后被革除 |
存放数据大小 | 4K 左右 | 个别为 5M | 个别为 5M |
与服务器端通信 | 每次都会携带在 HTTP 头中每次都会携带在 HTTP 头中 | 不与服务器通信 | 不与服务器通信 |
易用性 | 原生的 Cookie 接口不敌对,须要封装 | 接口易用 | 接口易用 |
18. 哪些信息适宜放到 cookie 中
cookie 的增多无疑会减轻网络申请的开销,而且每次申请都会将 cookie 残缺的带上,因而对于那些“每次申请都必须要携带的信息(如身份信息、A/ B 分桶信息等)”,才适宜放进 cookie 中,其余类型的数据倡议放进 localStorage 中。