多语言展示
当前在线:351今日阅读:113今日分享:31

Cookie技术的详解

Cookie与Session是Web开发中必不可少的两个概念,有些人简单的把它们理解为一个是客户端的存储机制,一个是服务器端的存储机制,而没有真正理解它们的原理和特性。随着Web应用的普及,SSO单点登录的推广,我们有必要深刻认识Cookie与Session的一些基本概念,只有这样才能让我们在日常的开发工作中将它们运用的得心应手。今天李苦李就结合HTTP协议和存储机制,分享一下Cookie的基本原理及其在Web用的应用。(一)Cookie的基本概念及设置 Cookie是在远程浏览器端存储数据并以此跟踪和识别用户身份的机制。从实现上来说,Cookie是存储在客户端的一小段数据,浏览器(即客户端)通过HTTP协议和服务器端进行Cookie的交互。注:在实际应用中能管理Cookie的客户端不仅仅只有浏览器,当然作为Web应用我们最常见的客户端即是浏览器,这个概念我们应该加以理解。 Cookie独立于语言存在,也就是说,不论是PHP还是JSP(亦或是Java、.Net等其他语言)设置的Cookie,其本质都是一样滴,客户端脚本Javascript都能读取到。从严格的意义上来讲,Cookie并不是由具体的某种语言实现的,这些语言做的仅仅是通过发送HTTP指令,告诉浏览器,最终由浏览器操作Cookie并返回给服务器端。因此,Cookie的真正实现者是浏览器。 举例来说,我们经常使用PHP设置Cookie,但实际上PHP并没有真正设置过Cookie,也可以说是PHP压根没有能力去设置Cookie,PHP能做的只是告诉浏览器,让浏览器去设置Cookie。简单点说,Cookie和PHP没有任何关系,只和浏览器相关,PHP只是遵循某种标准向浏览器发送指令,具体Cookie的设置与管理由浏览器完成。理解这一点,对我们学习Cookie的原理有至关重要的影响。设置Cookie需要注意以下几点:PHP函数setcookie()和setrawcookie()均可设置Cookie,它们都有一个boolean型的返回值,如果是false,代表设置失败;如果是true,代表设置成功。但这个返回值仅供参考,并不能保证100%客户端能够成功。由PHP(服务器端)设置的Cookie不能立即生效,要等到下一个页面才能生效。如果是客户端Javascript设置的,则是立即生效。Cookie没有显式的删除函数,如果想要删除Cookie,只能将Cookie的expire设置为过去的某个时间点,这样会自动触发浏览器删除Cookie。(二)PHP和JS对Cookie的操作 对HTTP协议有所了解的同学应该知道,Cookie是HTTP头的一部分,即先发送或请求Cookie,然后才是data域。因此,setcookie()等设置Cookie的相关函数必须在输出数据之前调用,这和header()函数是相同的。当然,我们也可以通过header()函数设置Cookie,但一般不推荐这么做,如:?1 header('Set-Cookie:name='www.likuli.com''); 下面我们给出用PHP设置Cookie的一个示例:?123 刷新页面,可以看到PHP页面打印Cookie结果如下:?1 array(2) { ['name']=> string(14)'www.likuli.com'['jscookie']=> string(14)'jscookie value'} 上面的例子告诉我们,Cookie属于浏览器,而跟具体的某种语言没有直接的关联。(三)Cookie的存储机制及应用 Cookie通常用来存储一些不是很敏感的信息,或者进行登录控制,也可以用来记住用户名、实现免密码登录、防止重复投票等。当然,用Cookie防止严格意义上的重复投票是远远不够的,但是对于大多数不需要做严格判断的场景,用Cookie还是能解决不少问题的。 前面提到的setcookie()函数的最后一个参数是HttpOnly,如果设置这个参数,则在客户端Javascript就无法读取到这个Cookie(在php.ini中也可以设置该参数)。某些时候,这么做能增加网站的安全性。该参数即是通知浏览器,屏蔽Javascript对Cookie的读取,但是通过其它方式还是可以查看Cookie的。当然,如果浏览器不支持,即是设置该参数,Javascript也是可以读取到的。正如前面所说,Cookie的设置从根本上还是取决于浏览器。 每个域名下允许的Cookie是有限制的,根据浏览器的不同这个限制也不同。具体浏览器的限制个数,各位同学可自行查阅。每个浏览器对于超限的Cookie,超过就删除旧的,并且一个Cookie最大字节数为4097(该数目可能会随着浏览器的升级而改变)。 在实际的应用中,Cookie确实能给我们带来不少用户体验和方便的功能。但Cookie并非越多越好,过多的Cookie会消耗过多的带宽。一旦Cookie被设置在某个域下,则请求该域名下的资源时,浏览器和服务器直接都可能存在Cookie的上行与下行流量。看似一个很小的Cookie,在一个页面请求中可能会产生十几kb的流量,所以最好不要滥用Cookie,更不要把Cookie当做客户端的存储器来用。 上文提到过,Cookie是保存在客户端的一小段数据,那么究竟是保存在什么地方呢?一般有两种情况:一种是保存在文件中;一种是保存在浏览器的内存中。这会根据不同浏览器的策略的不同而不同。 关闭浏览器,Cookie并不会随之消失。除非设置Cookie的expire为空,即随着浏览器的关系而消失。还有一种Cookie是由Flash创建的,即使清空浏览器的所有隐私数据,这类Cookie还是会存在硬盘。因为它们不受浏览器的控制,只受flash的控制。很多网站采用该方法识别用户。有兴趣的同学可以查阅相关方面的资料,再次不在阐述。(四)Cookie跨域与P3P协议 正常情况下Cookie只能在一个应用中使用,即一个Cookie只能被创建该Cookie的应用获取到。实现Cookie的跨域,主要是为了实现当前最流行的单点登录。最简单的实现Cookie跨域操作的方法即是使用P3P协议。有关P3P协议的东西,各位同学可查阅相关的网络资料,这里不做阐述。我们重点讲述怎么使用P3P协议实现Cookie的跨域。步骤一:编辑hosts文件,加入测试域名:?12 127.0.0.1 www.aaaaa.com127.0.0.1 www.bbbbb.com 步骤二:访问www.aaaaa.com时,调用www.bbbbb.com的页面,并设置Cookie:?1 www.bbbbb.com域名下set.php脚本的代码如下:?12 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,'/','.bbbbb.com'); 访问bbbbb域,查看Cookie,打印结果证明Cookie已生效。http://www.bbbbb.com/get.php,代码如下:?12 'www.likuli.com') 为了对比是否P3P协议已经生效,各位同学可自行实验在www.aaaaa.com域下直接设置bbbbb域下的Cookie,看是否生效。注意事项:Cookie跨域必须设置超时时间,否则跨域会取不到;使用FRAME和IFRAME时,一定要在相应的动态页的页头添加P3P的信息,否则IE会阻止Cookie,同样会取不到;IE对跨域访问Cookie限制比较严格,必须添加P3P头信息才能成功,其它浏览器(如Chrome、Firefox)不用设置P3P头信息即可成功。
推荐信息