cookie从哪来到哪去

做者:Jjavascript

从哪来

浏览器添加cookie的时机:java

  • 有客户端来设置:经过javascript的api——document.cookie来操做git

    设置
    document.cookie = 'name=value; maxAge=3000; path=/; domain=xx.com; secure'复制代码

    cookie的名和值中不能出现分号、逗号、等号和空格,每个key之间经过分号和空格来分割。github

    经过document.cookie的方式来设置cookie每次只能设置一个cookie。若是咱们写多个会有什么效果呢?ajax

    document.cookie = 'cookie1=value1; cookie2=value2'复制代码

    放在console中运行一下,会发现,只有第一个cookie1设置成功,而cookie2被无视了。因此要设置多个cookie,最简单的方式就是屡次调用document.cookie。chrome

  • 由服务端来设置:http的响应头中。api

    打开浏览器的控制台,在network下咱们能够看到浏览器发出的全部请求。这些请求的返回头中,有些会发现一个Set-Cookie的字段。
    跨域


    服务器经过这个字段来告诉浏览器,它须要设置一个cookie,而后浏览器检查一下要设置的内容是否知足浏览器定下的cookie的“条条框框”,若是知足那么一个cookie就诞生了。这里提到了“条条框框”咱们稍后作解答。

    在上图中,响应头里set-cookie字段能够有多个,每个对应一个要设置的cookie,且只能对应一个。浏览器

到哪去

  • 客户端主动获取安全

    和客户端设置相同,获取的时候也是经过document.cookie来读取:

    var cookies = document.cookie复制代码

    读取到的cookie为一串字符串,每一个cookie之间经过分号来分割。

  • 随着请求发送

    浏览器发送请求时,在请求的头中会自动将“符合条件”的cookie带上。
    既然是请求头中携带的,那么咱们经过ajax发送请求的时候,可否顺便设置一下cookie呢?简单的实验一下便可知晓:

    var xhr = new XMLHttpRequest();
      xhr.open('GET', url, true);
      xhr.withCredentials = true;
      xhr.setRequestHeader('Cookie', "key=value");
      xhr.send(null);复制代码

    而后咱们看看实际上浏览器发送出去的请求:


    咱们设置的cookie并无生效,而且chrome浏览器下咱们会看到一行报错

    Refused to set unsafe header "Cookie"

    因此说,由于浏览器的安全限制,咱们不能本身随便设置请求头中的cookie。

cookies条条框框

一个cookie除了value外,还有domain、path、expires/max-age、httpOnly、secure、sameSite这些属性。设置cookie的时候,能够对这些相关属性进行设置,固然也能够不进行设置,这时浏览器会自动给这些属性一个默认值。cookie的条条框框就和这些属性脱不了干系。

  • domain

    domain限制了cookie的使用范围:只能在domain值的范围中才能访问到该cookie.

    同时domain值的设置也有严格的要求。

    • 自身

      毫无疑问domain的值能够设置为自己。

    • 向下:全部子域名

      若是咱们当前页面的域名是 sub.test.com, 那么 domain 能够设置为.sub.test.com。容许全部sub.test.com的子域名访问,如xx.sub.test.com、xx.xx.sub.test.com。

    • 向上:父级域名,直到Top-Level的下一级

      若是咱们当前页面的域名是sub.test.com, 那么domain能够设置为test.com。可是不能设置为.com。由于.com属于Top-Level Domain

  • path

    domain+path 共同限制了可访问该cookie的URL。若是某个cookie的path='/home',那么只有“domain/home”下的全部url能够访问该cookie。

  • expires/max-age

    这两个值决定了cookie能活多久。若是不进行设置,那么浏览器会默认将cookie的有效期设置为 session,当页面关闭后cookie便随之被清理了。若是但愿cookie在页面关闭后,仍然能保存一段时间,那么就须要为cookie设置一个过时时间,在过时时间内浏览器都会为咱们保留该cookie.

    expires 是 http/1.0协议中的选项,在新的http/1.1协议中expires已经由 max-age 选项代替。expires必须是 GMT 格式的时间。

    max-age的单位为秒,cookie失效时刻 = 建立时刻 + max-age

  • httpOnly

    若是一个cookie被标记为httpOnly, 那么前文所提到的经过document.cookie的方式就没法获取到该cookie。一样的,咱们经过js来设置cookie的,也没法被标记为httpOnly。也就说如下写法是不会生效的:

    document.cookie="cookie1=value1; HttpOnly"复制代码

    这个值只能经过请求的响应头来设置。默认状况下,cookie不会带httpOnly选项。

  • Secure

    对于被标记为Secure的cookie,只有当请求是HTTPS或者其余安全协议时,该cookie 才能被访问到。一样的,也只有在HTTPS或者其余安全协议时,咱们也才能经过js设置secure的cookie。

  • sameSite

    这个值这是谷歌开发的一种安全机制,用来定义cookie如何跨域发送,其目的是尝试阻止CSRF。chrome51版本已经支持。关于各大浏览器的支持状况,参考chrome官网。关于这个特性,这里很少作介绍了,感兴趣的可参看preventing-csrf-with-samesite-cookie-attributegoodbye-csrf-samesite-to-the-rescue

    最后,这些全部的属性值,一块儿决定了一件事——这个cookie那个URL能够能用。

参考文献:
developers.livechatinc.com/blog/settin…
www.sjoerdlangkemper.nl/2016/04/14/…


欢迎关注DDFE
GITHUB:github.com/DDFE
微信公众号:微信搜索公众号“DDFE”或扫描下面的二维码