作为一个前端的程序员,操作cookie也仅仅是document.cookie。对于http cookie一般是server端接口来控制,通过Request Headers和Response Headers可以看到。平时也不胜关心。但是最近项目遇到一个问题,让我对http cookie的发送与设置进行了精分。
http cookie跨域时到底发送哪个域的数据
前提:页面的域名是:web.zmrdlb.com,请求接口的域名是web.zmrdlb.net。(接口已经设置了可以跨域访问,所以页面通过ajax可以访问接口的数据)
tips: 要想跨域可以发送cookie,则先设置ajax对象xhr.withCredentials = true;然后接口的Response Headers添加如下设置:
- 允许跨域一般设置:(这里说到要支持cookie,所以注意有cookie设置) - Access-Control-Allow-Headers: Origin, Content-Type, Cookie, Accept - Access-Control-Allow-Methods: GET, POST, PATCH, PUT, OPTIONS - Access-Control-Allow-Origin: http://web.zmrdlb.com (注意:如果要支持跨域传递cookie,则不能是*,必须是具体的域名) - cookie跨域设置: - Access-Control-Allow-Credentials: true
web.zmrdlb.com域名下,设置cookie:
- key: comname
- value: zmr
- domain: zmrdlb.com
- path: /
- expires: 2天后
web.zmrdlb.net域名下,设置cookie:
- key: netname
- value: dlb
- domain: web.zmrdlb.net
- path: /
- expires: 2天后
在web.zmrdlb.com域名的页面下,请求web.zmrdlb.net域名下的接口。
Request Headers:
Cookie: netname=dlb;
Response Headers:
Set-Cookie: netsex=man;domain=zmrdlb.net;path=/;httponly
- 此时再次请求接口
Request Headers:
Cookie: netname=dlb;netsex=man;
总结:
- http cookie发送的时候,Resquest Headers里面的cookie字段,是你请求的接口所属的域名和路径可以读取到的cookie;
- 不同子域可以共享二级域名及以上相同父域名的cookie;
- 特别说明:HTTP-only类型的Cookie不能使用Javascript通过Document.cookie属性来访问,从而能够在一定程度上阻止跨域脚本攻击(XSS)。但是document.cookie设置的cookie(所请求的接口可以访问到的)可以通过Request Headers中的Cookie来发送。
cookie的作用域
Domain和Path指令定义了Cookie的作用域,即需要发送Cookie的URL集合。这里要重点说一下domain
设置cookie(也包括document.cookie方式), 在chrome中的Application中查看cookie的Domain为:
如果没有指定domain,则默认是当前域名(放到业务里面,如果是document.cookie方式,则是页面域名;如果是请求接口,接口返回set-cookie,则是接口域名),仅仅是当前域名,不包括其子域。结果:web.zmrdlb.com;
如果指定了domain,则包括子域。比如设置domain=zmrdlb.com。结果:.zmrdlb.com (注意前面多了.);
第三方cookie
官方概念:
每个Cookie都有与之关联的域(Domain),如果Cookie的域和页面的域是一样的,那么我们称这个Cookie为第一方Cookie(first-party cookie),如果Cookie的域和页面的域不一样,则称之为第三方Cookie(third-party cookie.)。
第三方cookie发送:
大多数浏览器,都允许第三方cookie发送。这个时候涉及到跨域发送cookie。
跨域cookie踩坑:
最近做的一个项目,发送了跨域cookie。PC和Android都可以,放到ios就有问题了。排查了半天。
页面域名:web.zmrdlb.com
接口域名:web.api.zmrdlb.net
这个时候,请求接口返回了set-cookie。但是再次请求接口域名下的其他接口,在ios下,cookie老是带不上。
原因
ios对第三方cookie的发送多了一层限制。经测试发现,如果页面域名和接口域名没有共同的父域(二级域名或及以上),则无法发送cookie。
解决方案
接口域名改为:web.api.zmrdlb.com
其他案例
官方资料
ps
更多细节请参考官方资料。如遇更多精分,则及时补充。