Contents
  1. 1. 为什么使用cookies?
  2. 2. Cookie的工作原理
  3. 3. 创建 Cookie
  4. 4. Cookie的属性
    1. 4.1. domain 选项
    2. 4.2. path 选项
    3. 4.3. secure 选项
    4. 4.4. HTTP-only
  5. 5. 设置cookie的方式
  6. 6. Cookie的限制
  7. 7. 跨域传输 Cookie
  8. 8. Cookie的设置与读取
  9. 9. 总结
  10. 10. 参考

为什么使用cookies?

因为HTTP协议是无状态的,对于一个浏览器发出的多次请求,WEB服务器无法区分是不是来源于同一个浏览器。所以,需要额外的数据用于维护会话。 Cookie 正是这样的一段随HTTP请求一起被传递的额外数据。

Cookie的工作原理

Cookie 是浏览器提供的功能,用于存储服务器的一段文本信息,每个 Cookie 的大小一般不能超过4KB。浏览器每次向服务器发出 HTTP 请求,浏览器就会检查是否有域名相应的Cookie,如果有就会在 request header 中添加 Cookie 信息。

Cookie 本质上是浏览器存储数据的方式,只不过,这部分数据会自动携带到 Http 的请求头中。

Web 服务器通过发送一个称为 Set-Cookie 的 HTTP 消息头来创建一个 cookie,Set-Cookie 消息头是一个字符串,其格式如下(中括号中的部分是可选的):

1
Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]

Cookie的属性

每个cookie都有一定的属性,如什么时候失效,要发送到哪个域名,哪个路径等等。这些属性是通过cookie选项来设置的,cookie选项包括:expires、domain、path、secure、HttpOnly。在设置任一个cookie时都可以设置相关的这些属性,当然也可以不设置,这时会使用这些属性的默认值。在设置这些属性时,属性之间由一个分号和一个空格隔开。

代码示例如下:

1
"key=name; expires=Thu, 25 Feb 2016 04:18:00 GMT; domain=ppsc.sankuai.com; path=/; secure; HttpOnly"

domain 选项

指定了 cookie 将要被发送至哪个或哪些域中。默认情况下,domain 会被设置为创建该 cookie 的页面所在的域名,所以当给相同域名发送请求时该 cookie 会被发送至服务器。

主域下的 Cookie 会扩散到该主域下所有的子域上。例如:a.com有cookie,用户访问b.a.com时,也会获取到a.com下的cookie。

path 选项

path 选项指定了请求的资源 URL 中必须存在指定的路径时,才会发送Cookie 消息头。这个比较通常是将 path 选项的值与请求的 URL 从头开始逐字符比较完成的。如果字符匹配,则发送 Cookie 消息头,例如:

1
Set-Cookie:name=Scoolor; path=/blog

secure 选项

secure选项,不像其它选项,该选项只是一个标记而没有值。只有当一个请求通过 SSL 或 HTTPS 创建时,包含 secure 选项的 cookie 才能被发送至服务器。这种 cookie 的内容具有很高的价值,如果以纯文本形式传递很有可能被篡改,例如:

1
Set-Cookie: name=Scoolor; secure

HTTP-only

HTTP-Only 是告诉浏览器 cookie 不能通过 JavaScript 的 document.cookie 属性访问。设计该特征意在提供一个安全措施来帮助阻止通过 JavaScript 发起的跨站脚本攻击 (XSS) 窃取 cookie 的行为。

设置cookie的方式

  1. http response Set-Cookie

使用http Response Headers 可以通过浏览器自动设置cookie

  1. JavaScript set cookie

JavaScript也可以设置Cookie,本质与浏览器通过 Http response 获取cookie自动设置一致,只是JavaScript 帮浏览器进行了设置。在 JavaScript 中通过 document.cookie 属性,你可以创建、维护和删除 cookie。

Cookie的限制

  1. 单个域名的所有cookie的大小不能超过4KB,最后设置的cookie如果超过4KB限制,设置会失败。
  2. 单个域名cookie数量最多50个,safari和chrome没有数量限制。
  3. cookie数量越多,体积越大,便会影响服务器传输效率,所以要慎用cookie,只把必须要带给服务器的数据设置到cookie中。

现在很多应用都做了前后端的分离,会涉及到跨域传输Cookie的问题,当然不一定要使用HTTP request的方式发送cookie,可以直接放到URL中传输,哈哈哈。默认情况下,Cookie 不能跨域传输,如果要跨域传输,需要服务端同意,同时客户端需要开启withCredentials属性,具体如下:

1
2
3
4
5
6
浏览器设置:
xhr.withCredentials=true

服务端设置响应头:
Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin: http://www.xxx.com(注意这里设为*不行,没做测试)

Cookie的设置与读取

测试了若干种设置与读取的方式,可能不全,应该能涵盖到大多数情况。

  1. 相同域名,不可以跨路径设置与读取 Cookie
  2. 子域可以读取对应主域下的 Cookie,如a.b.com,可以读取b.com域下的cookie
  3. 子域可以设置对应主域下的 Cookie,如a.b.com,可以设置b.com域下的cookie
  4. Cookie 不可以跨域名设置与读取,即便是相同主域不同子域也不可以相互读取设置,如a.b.com不能设置b.b.com的cookie

总结

Cookie 存在时间已经很久远了,各个浏览器之前的处理方式也各有不同,这不是一篇系统性讲解的文章,这里不做太多介绍,只涉及一些比较通用的部分,希望帮助大家理解 Cookie。

参考

  1. https://www.cnblogs.com/yinian/p/8371746.html
  2. https://segmentfault.com/a/1190000004556040
  3. https://www.jianshu.com/p/090b971c048b
Contents
  1. 1. 为什么使用cookies?
  2. 2. Cookie的工作原理
  3. 3. 创建 Cookie
  4. 4. Cookie的属性
    1. 4.1. domain 选项
    2. 4.2. path 选项
    3. 4.3. secure 选项
    4. 4.4. HTTP-only
  5. 5. 设置cookie的方式
  6. 6. Cookie的限制
  7. 7. 跨域传输 Cookie
  8. 8. Cookie的设置与读取
  9. 9. 总结
  10. 10. 参考