PHP网络技术(五)——cookie及记住用户名功能实现
(原创内容,转载请注明来源,谢谢)
Cookie是存储在客户端(主要是浏览器)的信息,可以以此跟踪和识别用户。PHP无法直接操作Cookie,而是通过命令向浏览器发送命令,由浏览器对Cookie进行操作。
一、PHP设置cookie方式
1)setcookie(name,value,expire,path,domain,secure,httponly)
第一个参数是必填的,后面都是选填的。
name是cookie的名称,value不填则是空,value传输过程中会被使用urlencode进行转码。
expire是以秒计算的有效时间,如果有填的话则计时,浏览器关闭再打开还在;如果没填则计入内存,浏览器关闭再打开就没了。
path是有效路径,domain是作用域名(如果设置的不对会导致刷新或者重新打开浏览器时无法获取cookie),secure是加密传输(主要用于https)。
httponly如果是true则javascript无法操作此cookie,这有助于避免xss攻击。
2)setrawcookie
参数和setcookie都一样,区别在于value传输时不会被转码。
3)删除cookie方式
将cookie的expire设置成过去时间即可。
二、cookie存储机制
cookie通常用来存储相对不敏感的信息,例如记住用户名密码、登录控制等。由于cookie的存储是浏览器进行的操作,因此不同浏览器的存储机制也不相同。
1)存储位置
IE在每个域名下面保存一个文本文件,用于记录不同网站的cookie。Firefox将文件都存储在sqlite数据库中进行管理,但是为了安全,Firefox4以上的版本对文件进行了加密处理,只有特定的API才可以读取文件,其中存储了id、cookie名、值、对应的host、路径、失效时间、ishttponly等信息。
2)有效时间
如果设定cookie时,有设置expire,则关闭浏览器后再次打开浏览器,cookie还会存在。但是如果没有设定expire,则会被存入浏览器的内容,当浏览器关闭时cookie失效。另外,还有通过flash创建的cookie,称为flash shared object,其不受浏览器管理,即使浏览器清空数据仍会存在,只有格式化硬盘或者使用特定的软件才能删除。
3)数量限制
不同浏览器对每个域名下的cookie有所限制,IE8一个域名可以放50个cookie,firefox可以放150个。超过限制后,新的会把最旧的内容顶掉。
4)安全性
由于服务端和javascript都可以设置cookie,因此不够安全,可以通过ishttponly设置不允许javascript进行操作。但是即便如此,由于cookie可以用软件拼接进行发送,因此仍不安全,保密的信息不适合用cookie存储,如果要存储则必须进行加密。
5)占用资源
cookie使用可以带来好的用户体验,但是其占用带宽,由于客户端和服务端的通信都会带上cookie,因此,每次http请求会来回传送cookie共两次,占用上下行流量。因此不能滥用cookie,不要把cookie当作服务端的存储器进行使用。
三、跨域与P3P协议
cookie只能在一个应用中使用,即一个cookie只能有创建它的应用获得。但是如果一个项目有多个域名,需要实现跨域名获取cookie,则需要使用p3p协议。
1)P3P
P3P协议是为web用户提供对自己公开信息的更多控制,支持此协议的站点未浏览者声明他们的隐私策略。
P3P协议的使用,即要求共享某个cookie值的域名在cookie设置操作之前,加一个p3p的header头,且定义哪些域名可以访问该cookie,则被定义的域名可以直接获得此域名下的cookie。
2)实现方式
假设公司有两个域名,a.company.com和b.company.com,a域名需要共享某个cookie给b,方法如下。
a域名下的文件:
header(‘P3P:CP=”CURa AMDa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOIDSP COR”’);
setcookie(‘cookiename’,’value’,time()+3600, ‘/’, ‘.b.company.com’);
b域名下的文件:
$_COOKIE[‘cookiename’];
3)注意事项
页面cookie必须设置expire,否则无法生效;利用iframe时,需要在获取的相应动态页头添加P3P的信息,否则IE会把iframe的cookie阻止。
如果仅有两个域名,此操作很方便,但是如果网站涉及很多的域名,则需要用完整的单点登录(SSO)方案,现有比较成熟的方案是CAS。
CAS有关的博客如下。
http://www.coin163.com/java/cas/cas.html
http://www.cnblogs.com/lr393993507/p/5231432.html
四、本地存储(localStorage)
设置cookie会占用较多带宽,且目前对每个域名下的cookie限制4kb。因此当有大量内容需要存储在本地时,需要使用本地存储技术,此技术使用javascript可以实现。
1)浏览器支持
用一段js代码可以判断浏览器是否支持本地存储:window.localStorage,如果是true则是支持,否则不支持。
2)增删改查
a.添加方式较为灵活,有三种方式:
window.localStorage.key1 = ‘val1’ 或localStorage[‘key1’] = ‘val1’
或 localStorage.setItem(‘key1’, ‘val1’)
,当设置同样的key时,后面的设置会覆盖前面的设置。
另外,当不知道键名时,可以使用window.localStorage.key(i)获取第i个键名,因此也可以相应的用键获取值,可以用for循环获取所有的键。
b. 获取方式同样灵活,也有三种对应的方式:
window.localStorage.key1
或localStorage[‘key1’]
或 ocalStorage.getItem(‘key1’)
c. 删除分为删除单个与全部删除:
删除单个采用localStorage.removeItem(‘key1’)
,全部删除采用clear()
方法。
d. 事件监听
html5增加了对localStorage的事件监听,包括onstorage、storage等事件。
3)其他注意事项
任何格式的存储会被转换成字符串,因此如果需要存储数组等信息时,可以先用json将内容转换成特定格式的字符串,在取出时在转回去。
五、使用cookie实现记住用户名
1)功能
使用cookie实现记住用户名功能。
当每次重新刷新或加载页面,则去获取cookie,如果存在则赋值给输入框,如果不存在则将输入框制空。
设置保存用户名按钮,保存2小时。关闭浏览器再次打开仍然会存在。
设置取消保存,再次刷新则获取到空。
2)页面
a. 第一次打开
b. 输入用户名,点击记住用户名
c. 关闭浏览器,再次打开浏览器,发现用户名的cookie意见设置成功
d. 点击取消记住用户名
e. 刷新页面,发现用户名已经消失,关闭再次打开浏览器同样没有
3)实现源码
a. 引入jquery-1.12.3.min.js
b. index.php 样式页面以及js页面
<html>
<head>
<title>记住用户名</title>
<scripttype="text/javascript"src="jquery-1.12.3.min.js"></script>
</head>
<body>
用户名:<inputid="username" />
<buttonid="btnSave">记住用户名</button>
<buttonid="btnCancel">取消记住用户名</button>
</body>
</html>
<scripttype="text/javascript">
$(function(){
//读取页面时获取cookie
$.post("user.php",{type:'init'},function(result){
$("#username").val(result);
});
//保存用户名到cookie
$("#btnSave").click(function(){
var username =$('#username').val();
$.post("user.php",{type:'set',username:username},function(result){
alert('设置成功');
location=location;
});
});
//取消保存用户名到cookie,即直接设置失效
$("#btnCancel").click(function(){
$.post("user.php",{type:'unset'},function(result){
alert('取消成功');
location=location;
});
});
});
</script>
c. user.phpcookie处理页面
<?php
//获取类型
$type =$_POST['type'];
if('init'== $type){
//初始化页面,如果有内容则赋值,否则制空
if(isset($_COOKIE['username'])){
echo $_COOKIE['username'];
}else{
echo '';
}
}elseif('set' == $type){
//设置cookie
$username = $_POST['username'];
setcookie('username', $username,time()+36000, '/', '127.0.0.1', false, true);
}else{
//取消保存用户名到cookie,即直接设置失效
setcookie('username', $username,time()-36000, '/', '127.0.0.1', false, true);
}
4)注意事项
setcookie需要注意domain的设置,一开始domain我设置的不对,导致刷新页面一直没有反应。并且在设置过程用firefox查看本地cookie有设置。经过反复调试,发现domain设置的不对导致此结果。
——written by linhxx 2017.07.24