初学者容易将cookie和session搞混淆,也有很多人简单的把cookie和session简单的理解为一种为客户端存储机制,另外一种为服务端存储机制。实际上cookie和session不仅是这么简单的,这一章就来详细讲解下关于cookie和session的内容。javascript
1 Cookie的基本概念和设置php
Cookie是一种存储在客户端的数据,能存储cookie的客户端不仅是浏览器,但绝大多数状况下都是由浏览器来实现。浏览器经过http协议和服务端进行cookie交互。Cookie是独立于语言而存在的,不少种语言均可以设置和读取cookie。在实现过程当中,编程语言是经过指令通知浏览器,而后是浏览器实现设置cookie的功能的。而读取cookie则是经过浏览器请求服务端时携带的http头部中的cookie信息得来的。html
PHP中可以使用setcookie()来设置cookie,语法以下:java
bool setcookie ( string $name [, string $value = "" [, int $expire = 0 [, string $path = "" [, string $domain = "" [, bool $secure = false [, bool $httponly = false ]]]]]] )web
setcookie可定义cookie并将其随http头部一块儿发送给客户端,在设置cookie以前不能有任何输出。当cookie被设置后,可在刷新页面后经过$_COOKIE全局数组得到。sql
第一个参数name是必选参数,表示cookie的名称,cookie的值是经过$_COOKIE[name]得到的。数据库
第二个参数是设置的cookie的值,存储在客户端。编程
第三个参数是设置cookie的有效时间,以秒为单位,若是想要删除一个函数能够将cookie的有效时间设置为当前时间以前,或者使用unset($_COOKIE[name])来删除某个cookie。若是不设置这个值,当浏览器关闭时,cookie会随之失效。数组
参数path设置cookie的有效目录,若是设置为”/“则表示在当前目录下都可用,若是设置为”/foo/“则表示只有在目录 “/foo/“ 和其子目录如”/foo/bar/“下才可。浏览器
参数domain设置cookie的做用域名,默认在本域名下有效。若是设置该值为”Example Domain则改该域名下的全部子域名如i.e.w2.Example Domain均可使用该cookie。若是要设置一个域名的全部子域名均可使用,则设置其值为如example.com便可。
参数secure用来设置是否对cookie进行加密传输,默认为false。若是设置为true,则只有在使用https的时候才会设置cookie。
第七个参数若是为true则表示只能经过http协议才能访问该cookie,意味着客户端javascript就不可操做这个cookie。使用此参数可减小XSS攻击的风险。
下面使用PHP分别设置三个cookie:
<?php setcookie('name','chenxiaolong'); setcookie('num','100',time()+100,'/foo/'); setcookie(‘gender’,'male',time()+100,'','百度一下,你就知道'); print_r($_COOKIE); ?>
第一个cookie设置名为name,值为chenxiaolong ,其余参数都是默认值,表示在当前目录和域名下都有效,且有效时间持续到浏览器关闭。第二和第三个cookie的设置只在特定的目录域名和有效时间内才能看到。注意当第一次在浏览器访问这个脚本文件时,并不会有任何的输出,由于设置完cookie后,须要刷新页面在下次请求时http头部才会携带上一次设置的cookie信息,这时才能读取到cookie。
第一次在浏览器访问该脚本的请求消息头(Request Headers)和响应消息头(Response Headers)分别以下:
Request Headers: Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Encoding:gzip, deflate, sdch, br Accept-Language:zh-CN,zh;q=0.8 Cache-Control:max-age=0 Connection:keep-alive Host:localhost Upgrade-Insecure-Requests:1 User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
可见其并无携带任何的cookie信息,说明浏览器并无向客户端发送任何的cookie信息,而返回的响应消息头中包含了cookie信息。
Response Headers: Connection:Keep-Alive Content-Length:10 Content-Type:text/html; charset=UTF-8 Date:Sun, 13 Nov 2016 08:48:14 GMT Keep-Alive:timeout=5, max=100 Server:Apache/2.4.16 (Unix) PHP/7.0.5 Set-Cookie:name=chenxiaolong Set-Cookie:num=100; expires=Sun, 13-Nov-2016 08:49:54 GMT; Max-Age=100; path=/foo/ Set-Cookie:gender=male; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=-1479026884; domain=百度一下,你就知道 X-Powered-By:PHP/7.0.5
返回消息头中包含三个 Set-Cookie 部分,这是通知浏览器设置对应的Cookie。当咱们再次刷新页面的时候,可看到请求消息头中携带了Cookie信息。刷新请求的获得的请求消息头以下:
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Encoding:gzip, deflate, sdch, br Accept-Language:zh-CN,zh;q=0.8 Cache-Control:max-age=0 Connection:keep-alive Cookie:name=chenxiaolong Host:localhost Upgrade-Insecure-Requests:1 User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36 Name
可见其中已经携带了Cookie信息,可是只有设置的name这一个Cookie,这是由于其余两个Cookie不在这个目录或本域名下有效。
咱们在前面已经讲过,既然PHP和客户端javascript均可以操做cookie,那么用php设置的cookie也可用javascript读取到,用javascript设置的cookie也可由php读取到。不一样的时,php设置的cookie须要在刷新页面后的下一次请求中才有效,而javascript设置的cookie在本次请求中既有效。
以下用javascript代码设置cookie:
<script type="text/javascript"> function setCookie(name,value) { var Days = 30; var exp = new Date(); exp.setTime(exp.getTime() + Days*24*60*60*1000); document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString(); } function getCookie(name) { var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)"); if(arr=document.cookie.match(reg)) return unescape(arr[2]); else return null; } setCookie('test','testhaha'); alert(getCookie('test')); </script>
浏览器访问本页用javascript设置的cookie会当即生效。咱们再来看访问这个页面的请求消息头和响应消息头,分别以下。
Request Headers: Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Encoding:gzip, deflate, sdch, br Accept-Language:zh-CN,zh;q=0.8 Cache-Control:max-age=0 Connection:keep-alive Cookie:test=testhaha Host:localhost Upgrade-Insecure-Requests:1 User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
因为使用的是javascript在客户端设置的cookie,因此在本次向服务端发送http请求时就已经携带了cookie信息。咱们再用php代码 echo $_COOKIE[‘test']; 来得到由javascript设置的cookie,此时可在页面成功打印出名为test的cookie的值。经过这个例子咱们更清晰的知道,cookie是由编程语言经过一些指令告知浏览器设置的,由浏览器实现,在浏览器和服务端进行通讯时,在http消息头中携带cookie信息。
2 cookie的应用和存储机制
Cookie常常用来存储一些不敏感的信息,可用来防止刷票,记录用户名,限制重复提交等。
以防止用户在一分钟以内屡次提交为例,代码以下:
<script type="text/javascript">
function SetCookie(name, value) { var Days = 30; var exp = new Date(); exp.setTime(exp.getTime() + 60 * 100);//过时时间 1分钟 document.cookie = name + "=" + escape(value) + ";expires=" + exp.toGMTString(); } function submit() { if(getCookie('submit')) { alert('you haved submited before,please submit after one minute'); } else { SetCookie('submit','yes'); } } function getCookie(name) { var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)"); if(arr=document.cookie.match(reg)) return unescape(arr[2]); else return null; } </script> <button onclick='submit()'>提交</button>
以上代码实现的是防止用户在一分钟以内屡次提交表单,当用户第一次提交表单时,设置cookie有效期为1分钟,当再次点击提交时,判断cookie是否过时来限制用户的提交。
前面说,Cookie是存储在客户端的一段数据。可是不一样的浏览器存储Cookie的地方不一样,一种是将Cookie数据保存在文件中,另外一种是保存在浏览器内存中。
在Windows系统上(这里以Win7为例)。IE浏览器Cookie数据位于%APPDATA%MicrosoftWindowsCookies 目录中的xxx.txt文件 ,里面可能有不少个.txt Cookie文件,如:C:Usersyren9AppDataRoamingMicrosoftWindowsCookies0WQ6YROK.txt
在IE浏览器中,IE将各个站点的Cookie分别保存为一个XXX.txt这样的纯文本文件;而Firefox和Chrome是将全部的Cookie都保存在一个文件中,该文件的格式为SQLite数据库格式的文件。Firefox的Cookie数据位于:%APPDATA%MozillaFirefoxProfiles 目录中的xxx.default目录,名为cookies.sqlite的文件。如:C:UsersjayAppDataRoamingMozillaFirefoxProfilesji4grfex.defaultcookies.sqlite
在Firefox中查看cookie, 能够选择”工具 > 选项 >” “隐私 > 显示cookie”。Chrome的Cookie数据位于:%LOCALAPPDATA%GoogleChromeUser DataDefault 目录中,名为Cookies的文件。如:C:UsersjayAppDataLocalGoogleChromeUser DataDefaultCookies 。
本文节选自 《php7实践指南》 陈小龙著
微信扫一扫,发现更多内容