Cookie总结

在刚学web的时候就了解了cookie,只是并没有在项目中用到过,对它的一些细节也没有仔细了解过,最近重构一个单点登录的项目,其中用到了cookie,现对一些自己之前没有注意的点进行总结下。

cookie的属性选项

cookie选项包括:expiresdomainpathsecureHttpOnly。在设置任一个cookie时都可以设置相关的这些属性,当然也可以不设置,这时会使用这些属性的默认值。

expires(max-age)

expires选项用来设置cookie失效日期。对于失效的cookie浏览器会清空。如果没有设置该选项,则默认有效期为session,即会话cookie。这种cookie在浏览器关闭后就没有了。

expires 是 http/1.0协议中的选项,在新的http/1.1协议中expires已经由 max-age 选项代替,两者的作用都是限制cookie的有效时间。expires的值是一个时间点(cookie失效时刻= expires),而max-age 的值是一个以秒为单位时间段(cookie失效时刻= 创建时刻+ max-age)。另外,max-age 的默认值是 -1(即有效期为 session );若max-age有三种可能值:负数、0、正数。负数:有效期session;0:删除cookie;正数:有效期为创建时刻+ max-age

domain和path

domain是域名,path是路径,domainpath一起来限制 cookie 能被哪些 URL 访问。

一句话概括:某cookie的 domain为“baidu.com”, path为“/ ”,若请求的URL(URL 可以是js/html/img/css资源请求,但不包括 XHR 请求)的域名是“baidu.com”或其子域如“api.baidu.com”、“dev.api.baidu.com”,且 URL 的路径是“/ ”或子路径“/home”、“/home/login”,则浏览器会将此 cookie 添加到该请求的 cookie 头部中。

所以domainpath2个选项共同决定了cookie何时被浏览器自动添加到请求头部中发送出去。如果没有设置这两个选项,则会使用默认值。domain的默认值为设置该cookie的网页所在的域名,path默认值为设置该cookie的网页所在的目录。

domain是可以设置为页面本身的域名(本域),或页面本身域名的父域,但不能是公共后缀 public suffix。举例说明下:如果页面域名为 www.baidu.com, domain可以设置为“www.baidu.com”,也可以设置为“baidu.com”,但不能设置为“.com”或“com”。

关于细节,接下来会有讨论。

secure

secure选项用来设置cookie只在确保安全的请求中才会发送。当请求是HTTPS或者其他安全协议时,包含secure 选项的cookie 才能被发送至服务器。

默认情况下,cookie不会带secure选项(即为空)。所以默认情况下,不管是HTTPS协议还是HTTP协议的请求,cookie 都会被发送至服务端。但要注意一点,secure选项只是限定了在安全情况下才可以传输给服务端,但并不代表你不能看到这个 cookie。

httpOnly

这个选项用来设置cookie是否能通过 js 去访问。默认情况下,cookie不会带httpOnly选项(即为空),所以默认情况下,客户端是可以通过js代码去访问(包括读取、修改、删除等)这个cookie的。当cookiehttpOnly选项时,客户端则无法通过js代码去访问(包括读取、修改、删除等)这个cookie

在客户端是不能通过js代码去设置一个httpOnly类型的cookie的,这种类型的cookie只能通过服务端来设置。


cookie域的详细讨论

现在有如下3个域名,一个顶级域名、一个二级域名和一个三级域名:

① zydya.com
②blog.zyday.com
③one.blog.zyday.com

  • 首先在①zyday.com域名下设置cookie,做四次测试,分别设置domain参数为空、'zyday.com'、'blog.zyday.com'与'one.blog.zyday.com'。
    √表示该域名下能取到cookie,×表示不能取到cookie

domain参数
zydya.comblog.zyday.comone.blog.zyday.com
setcookie('name',1,time()+1)
 √ √ √
setcookie('name',1,time()+1,'/','zyday.com')
  √ √
setcookie('name',1,time()+1,'/','blog.zyday.com')
 × × ×
setcookie('name',1,time()+1,'/','one.blog.zyday.com')
×××
当domain设置为空时,domain默认为当前域名,并且该域名下的子域名都可以接收到cookie。但是domain参数设置其子域名时,所有域名就接收不到了,包括那个子域名。
  • 然后在②blog.zyday.com域名下设置cookie,测试条件同上
domain参数zydya.comblog.zyday.comone.blog.zyday.com
setcookie('name',1,time()+1)×
setcookie('name',1,time()+1,'/','zyday.com')
setcookie('name',1,time()+1,'/','blog.zyday.com')×
setcookie('name',1,time()+1,'/',one.blog.zyday.com')×××

看第二行,domain参数是zyday.com,是blog.zyday.com的父域名,那么zyday.com下所有子域名(包括zyday.com、blog.zyday.com、one.blog.zyday.com)都能接收到cookie。
当domain为自身域名时,那么其父域名受影响,其本身与其子域名可以接收到cookie。而设置其子域名或其他域名时,所有域名都接收不到cookie了。

  • 最后在③one.blog.zyday.com域名下设置cookie
domain参数zydya.comblog.zyday.comone.blog.zyday.com
setcookie('name',1,time()+1)××
setcookie('name',1,time()+1,'/','zyday.com')
setcookie('name',1,time()+1,'/','blog.zyday.com')×
setcookie('name',1,time()+1,'/',one.blog.zyday.com')××


总结:

1.在setcookie中省略domain参数,那么domain默认为当前域名。

2.domain参数可以设置父域名以及自身,但不能设置其它域名,包括子域名,否则cookie不起作用。

那么cookie的作用域:domain本身以及domain下的所有子域名。

跨域cookie的一种实现方式

在开发中我们会遇到cookie跨域访问的问题,比如单点登录。下面是一种解决方案。

现在有两个域名a.com和b.com,需要在a.com中设置cookie,并且在b.com中可以访问到。常规的做法是不行的。

1.在a.com中的页面中添加一个iframe,iframe的src指向b.com的一个请求,假如叫做b.com/setCookie.jsp。当然你也可以通过这个请求传递参数,在b.com/setCookie.jsp中接受做处理。

2.在b.com/setCookie.jsp中设置cookie。当然还需要借助p3p协议:

asp.net设置p3p的方法:

HttpContext.Current.Response.AddHeader("p3p", "CP=\""IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\""")

PHP设置p3p的方法:

header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"'); 

JSP设置p3p的方法:

response.setHeader("P3P","CP='IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT'")



参考链接:

https://segmentfault.com/a/1190000004556040

http://blog.csdn.net/czhphp/article/details/65628977

http://www.cnblogs.com/waters/articles/2869855.html

http://www.cnblogs.com/meteoric_cry/archive/2011/10/24/2223086.html



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值