Cookie

277 阅读4分钟

Cookie

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

2.Cookie主要用来分辨两个请求是否来自同一浏览器,以及用来保存一些状态信息,主要有:

1.对话(session会话)管理:保存登录,购物车等需要记录的信息
2.个性化:保存用户的偏好,比如网页字体的大小,背景色等等
3.追踪:记录和分析用户行为
有些开发者使用 Cookie 作为客户端储存。这样做虽然可行,但是并不推荐,
因为 Cookie 的设计目标并不是这个,它的容量很小(4KB),缺乏数据操作接口,
而且会影响性能。客户端储存应该使用 Web storage API 和 IndexedDB。

3.用户访问网址www.example.com,服务器在浏览器写入一个 Cookie。这个 Cookie 就会包含www.example.com这个域名,以及根路径/。这意味着,这个 Cookie 对该域名的根路径和它的所有子路径都有效。如果路径设为/forums,那么这个 Cookie 只有在访问www.example.com/forums及其子路径时才有效。以后,浏览器一旦访问这个路径,浏览器就会附上这段 Cookie 发送给服务器。

浏览器可以设置不接受 Cookie,也可以设置不向服务器发送 Cookie。window.navigator.cookieEnabled属性返回一个布尔值,表示浏览器是否打开 Cookie 功能。

4.浏览器的同源政策规定: 两个网址只要域名相同,端口相同,就可以共享Cookie

!!注意,这里不要求协议相同。也就是说,http://example.com设置的 Cookie,可以被https://example.com读取。

Cookie and Http

1.Cookie主要由http协议提供,也主要供http协议使用

2.服务器如果希望在浏览器保存 Cookie,就要在 HTTP 回应的头信息里面,放置一个Set-Cookie字段

Set-Cookie:foo=bar

//也可以生成多个
HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry

[page content]

//还可以附加属性
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

如果服务器想改变一个早先设置的 Cookie,必须同时满足四个条件:
Cookie 的key、domain、path和secure都匹配。
举例来说,如果原始的 Cookie 是用如下的Set-Cookie设置的。
Set-Cookie: key1=value1; domain=example.com; path=/blog
改变上面这个 Cookie 的值,就必须使用同样的Set-Cookie。
Set-Cookie: key1=value2; domain=example.com; path=/blog
只要有一个属性不同,就会生成一个全新的 Cookie,而不是替换掉原来那个 Cookie

3.Http请求: Cookie的发送

浏览器向服务器发送http请求时,每个请求都会带上相应的Cookie信息,就是说,把服务器早前保存在浏览器的这段信息,再发回服务器。这时要使用 HTTP 头信息的Cookie字段

Cookie: foo=bar//向服务器发送名为foo的 Cookie,值为bar
Cookie字段可以包含多个Cookie,使用;分隔,如:
GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry

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

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

Cookie的属性

Expires,Max-Age

如果Set-Cookie字段没有指定Expires或Max-Age属性,那么这个 Cookie 就是 Session Cookie,即它只在本次对话存在,一旦用户关闭浏览器,浏览器就不会再保留这个 Cookie。 Max-Age的值优先于Expires

Domain Path

Domain属性是指定浏览器发出HTTP请求时,那些域名要附带这个Cookie,如果没有指定该属性,浏览器会默认将其设置为当前URL的一级域名,比如www.example.com会设为example.com,而且以后如果访问example.com的任何子域名,HTTP 请求也会带上这个 Cookie。

如果服务器在Set-Cookie字段指定的域名,不属于当前域名,浏览器会拒绝这个 Cookie。

Secure,HttpOnly

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

HttpOnly指定该Cookie无法通过Javascript脚本拿到,主要是Document.cookie属性、XMLHttpRequest对象和 Request API 都拿不到该属性。这样就防止了该Cookie被脚本读到,只有浏览器发出http请求的时候,才会带上该Cookie

document.cookie

document.cookie用于读写当前网页的Cookie. 读取的时候,它会返回当前网页的所有Cookie,前提是该cookie没有httpOnly属性

document.cookie属性是可写的,可以通过它为当前网站添加 Cookie。
document.cookie = 'fontSize=14';