圣泉山人 后端开发工程师

Cookie与P3P

2015-02-10

Cookie是什么?

Cookie是存储在客户端的一段数据,客户端通过HTTP协议和服务器端进行Cookie交互,并以此跟踪和识别用户。

Cookie独立于语言存在,语言都是通过和客户端(比如浏览器)交互,让客户端去管理,语言本身是没有能力去设置cookie的。

php设置Cookie

  • setcookie($name [,$val, $expire=0, $path, $domain, $secure=false, $httponly=false])
  • setrawcookie()

两者的功能和参数基本一样,唯一区别是setrawcookie()不会对Cookie中的value进行urlencode转码

参数详解

  • $name : 必选参数,值是cookie的名称
  • $val : 用来设置cookie的值,为空时,cookie值为空,客户端会尝试删除掉这个cookie,因此想保存false,建议用0来代替
  • $expire : 设置秒为单位的有效时间
  • $path :设置cookie的有效目录,默认为’/’,即整个域名下有效,也可以设置仅在某个目录有效
  • $domain :设置cookie的作用域名,默认在本域名下,需注意在ie下,包括点号长度小于等于5的短域名设置了该参数,会导致cookie设置失败
  • $secure :设置是否对cookie进行加密传输,默认为false,如果设置为true,只有使用HTTPS,这个cookie才会被设置
  • $httponly :是否只是用http访问cookie,如果为1或者true,客户端的js就无法操作cookie,不是所有浏览器都支持该参数

设置cookie注意要点

  • 上面俩函数有返回值,设置失败返回false,设置成功返回true,但是不代表客户端最终的设置结果
  • PHP在当前页面设置的cookie不能立即生效,要到下一个页面才看的到,因为还没有传递给客户端,如果是js设置的,是立即生效的
  • cookie没有显示的删除函数,如果想删除,需要把$expire设置为已过期时间,以触发浏览器的删除机制
  • cookie是http头的一部分,先发送或者请求cookie,然后才是data域,因此cookie的设置和header的设置差不多,要在输出前面进行
  • Cookie不是越多越好,因为它会增加带宽
  • 不要把Cookie当做客户端的存储器来使用

Cookie跨域与P3P协议

正常的cookie只能在一个应用中共享,比如在a域名下设置b域名的cookie就属于跨域设置,正常情况下是不能设置成功的。

为了实现跨域共享,统一应用平台,即实现单点登录,最简单的方式是使用P3P协议。

P3P跨域设置cookie的实现:

  • 有如下俩个测试域名:www.a.com 、www.b.com
  • 在www.b.com的a.php中调用www.b.com的b.php页面,同时设置cookie

a.php中代码:

//也可以通过iframe来实现
<script src="http://www.b.com/b.php?name=myy"></script>

b.php中代码:

<?php
//P3P header允许跨域访问隐私数据,从而可以跨域set-cookie成功
header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');

setcookie('name', $_GET['name'], time()+3600, '/', '.b.com');
  • 在www.b.com下加一个查看cookie的文件c.php,代码如下
<?php
var_dump($_COOKIE);
  • 访问a.php后,就可以访问c.php查看下cookie是否设置成功了。

注意的地方:

  • 用script方式,如果用firfox、chrome浏览器测试,不加p3p header头也可以设置成功,但是ie上面对cookie的限制比较严格,就必须加上header才行。
  • 页面的cookie不能是浏览器进程的cookie(比如未设置过期时间的cookie),否则跨域会取不到
  • 如果一个系统下有较多域名,相互操作对方的cookie就会变得很复杂,此时需要一个更完整的SSO方案

参考: 《PHP核心技术与最贱实践》


下一篇 PHP错误处理

Comments

Content