session和cookie的知识总结
1、HTTP协议
由HTTP客户端发起一个请求,建立一个到服务器指定端口(默认是80端口)的TCP连接。HTTP服务器则在那个端口监听客户端发送过来的请求。一旦收到请求,服务器(向客户端)发回一个状态行,比如"HTTP/1.1 200 OK",和(响应的)消息,消息的消息体可能是请求的文件、错误消息、或者其它一些信息。(引自百度百科)总之,客户端通过http协议request发送请求到服务器端,服务器端做出响应response。http协议最大的特点是无连接、无状态。无连接指每次请求响应完连接关闭。设计者的初衷是在互联网大量的访问下避免资源的浪费,随着页面资源的丰富多彩,页面包含图片、视频、文字等信息,每次请求都建立一个连接性能很低效,在后来的HTTP/1.0中以及HTTP/1.1中,引入了重用连接的机制,就是在http请求头中加入Connection: keep-alive
来告诉对方这个请求响应完成后不要关闭,下一次咱们还用这个请求继续交流。协议规定HTTP/1.0如果想要保持长连接,需要在请求头中加上Connection: keep-alive
,而HTTP/1.1默认是支持长连接的,有没有这个请求头都行。HTTP无状态,是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
2、cookie和session的本质
cookie和session都是针对http协议无状态而提出的一种保存客户端和服务器端保持连接状态的机制。
3、cookie简介
cookie最早是网景公司在93年发明的这样的技术。主要是用来达成客户端和服务器端持续连接的状态,来解决无状态的问题,让服务器知道用户是谁。cookie总是保存在客户端中,根据存储位置可以划分为两类,一种是内存cookie,一种是硬盘cookie。内存cookie是由浏览器保存在内存中,浏览器关闭后就消失了,存在时间短暂。硬盘cookie是存储在硬盘中的,可以设置过期时间,除非用户清理cookie或者时间过期,存储在硬盘中的cookie不会消失,存在时间长期。永久登陆、网站换肤、购物车等可以用cookie实现。
3.1 cookie操作(以php为例)
设置cookie
bool setcookie ( string $name
[, string $value
= "" [, int $expire
= 0 [, string $path
= "" [, string $domain
= "" [, bool $secure
= false [, bool $httponly
= false ]]]]]] )
setcookie() 定义了 Cookie,会和剩下的 HTTP 头一起发送给客户端。 和其他 HTTP 头一样,必须在脚本产生任意输出之前发送 Cookie(由于协议的限制)。 请在产生任何输出之前(包括 <html> 和 <head> 或者空格)调用本函数。
一旦设置 Cookie 后,下次打开页面时可以使用 $_COOKIE 读取。 Cookie 值同样也存在于 $_REQUEST。
name
-
Cookie 名称。
value
-
Cookie 值。 这个值储存于用户的电脑里,请勿储存敏感信息。 比如
name
是 'cookiename', 可通过 $_COOKIE['cookiename'] 获取它的值。 expire
-
Cookie 的过期时间。 这是个 Unix 时间戳,即 Unix 纪元以来(格林威治时间 1970 年 1 月 1 日 00:00:00)的秒数。 也就是说,基本可以用 time() 函数的结果加上希望过期的秒数。 或者也可以用 mktime()。 time()+60*60*24*30 就是设置 Cookie 30 天后过期。 如果设置成零,或者忽略参数, Cookie 会在会话结束时过期(也就是关掉浏览器时)。
Note:
你可能注意到了,
expire
使用 Unix 时间戳而非 Wdy, DD-Mon-YYYY HH:MM:SS GMT 这样的日期格式,是因为 PHP 内部作了转换。 path
-
Cookie 有效的服务器路径。 设置成 '/' 时,Cookie 对整个域名
domain
有效。 如果设置成 '/foo/', Cookie 仅仅对domain
中 /foo/ 目录及其子目录有效(比如 /foo/bar/)。 默认值是设置 Cookie 时的当前目录。 domain
-
Cookie 的有效域名/子域名。 设置成子域名(例如 'www.example.com'),会使 Cookie 对这个子域名和它的三级域名有效(例如 w2.www.example.com)。 要让 Cookie 对整个域名有效(包括它的全部子域名),只要设置成域名就可以了(这个例子里是 'example.com')。
旧版浏览器仍然在使用废弃的 » RFC 2109, 需要一个前置的点 . 来匹配所有子域名。
secure
-
设置这个 Cookie 是否仅仅通过安全的 HTTPS 连接传给客户端。 设置成
TRUE
时,只有安全连接存在时才会设置 Cookie。 如果是在服务器端处理这个需求,程序员需要仅仅在安全连接上发送此类 Cookie (通过 $_SERVER["HTTPS"] 判断)。 httponly
-
设置成
TRUE
,Cookie 仅可通过 HTTP 协议访问。 这意思就是 Cookie 无法通过类似 JavaScript 这样的脚本语言访问。 要有效减少 XSS 攻击时的身份窃取行为,可建议用此设置(虽然不是所有浏览器都支持),不过这个说法经常有争议。 PHP 5.2.0 中添加。TRUE
或FALSE
更新cookie
更新cookie和设置cookie用同一个函数即可。需要注意的是cookie的相关参数必须与设置时相同否则更新失败。
查看cookie
cookie数据都会保存在$_COOKIE的超全局数组中
删除cookie
删除cookie同样是使用setcookie()函数,只需将值设为空,过期时间设为当前时间之前的时间比如(time()-1)就可以删除cookie,与更新cookie相同,删除cookie时后面的参数也必须与设置时一致否则是删除不了的。
cookie的常用操作我封装在一个类中方便使用。可以点击查看
4、session简介
Session 是 用于保持状态的基于 Web服务器的方法。Session 允许通过将对象存储在 Web服务器的内存中在整个用户会话过程中保持任何对象。
session的工作原理:
4.1、准备建立会话的时候,php会查看请求中是否包含session_id。如果没有服务器会在自己的内存里创建一个新的变量,这个变量就是session_id.
4.2、服务器会把这个session_id发送到浏览器保存,一般浏览器会把这个id保存在cookie中。
4.3、之后每次浏览器访问服务器的时候,都会携带cookie中存储的这个session_id值,这样服务器就认识这个浏览器了。
4.4、服务端这个session_id的变量就可以存放任意的会话数据,这样数据是经过序列化之后存放进去的。
4.5、每次浏览器访问服务器,都可以凭借的session_id到服务器的这个变量中认领自己的信息
4.6、如果想销毁会话,可以删除会话中的数据,销毁会话文件,默认是存储在文件中的。也可以自定义存储在数据库中或者缓存中。
php中如何使用session
1、开启会话:session_start();
2、可以通过$_SESSION来设置相关值,设置和读取都是用这个全局变量。
3、销毁session session_destory();
这是没设置之前的截图
<?php //开启会话 session_start(); header('content-type:text/html;charset=utf-8'); $_SESSION['username']='张三'; $_SESSION['age']=18; echo 'session的名字:'.session_name().'<br>'; echo 'session的ID:'.session_id(); setcookie(session_name(),session_id(),time()+60*60);
运行这个文件之后,
由于在代码中自己设置了一个cookie设置了过期时间,所以这里有两个cookie
第一次访问后的截图可以看到请求头中是不包含session_id的信息的。
再来看第二次访问的结果:
<?php session_start(); header('content-type:text/html;charset=utf-8'); var_dump($_SESSION);
服务器会根据sessionid的信息查看文件获取数据。
可以看到文件存储的序列化后的信息。
销毁会话:
<?php //销毁session步骤 //1、将$_SESSION清除 $_SESSION=[]; //2、将cookie中的sessionid删除 setcookie(); //3、销毁会话 session_destory session_start(); //将$_SESSION 数据清空 $_SESSION=[]; //删除会话cookie if(ini_get('session.use_cookies')){ $params=session_get_cookie_params();//获取会话 cookie 参数 var_dump($params); setcookie(session_name(),session_id(),time()-1,$params['path'],$params['domain'],$params['secure'],$params['httponly']); setcookie(session_name(),session_id(),time()-1); } //销毁会话 session_destroy();
第一个删除cookie信息是删除默认的cookie信息,第二个是删除自己设置的cookie信息 只删除一个是没用的
至此,session从建立到删除的过程结束。
下面简述下当用户禁用浏览器的cookie时设置session的方法。
原理:只要吧sessionid传递给服务器就可以,因此可以通过url传递值,当然这样没有cookie安全。这里以火狐浏览器为例
首先,禁用浏览器cookie
注意:如果你正在登陆博客的话 操作会让你的登陆注销的。悲催的我写着这篇文章的时候,屏蔽后让我先登录,卧槽,幸亏没有在原页面跳转,不然我一上午的辛苦就白费了,与君共勉。
废话少说,题接上文。
禁用cookie后
<?php // 当用户禁用cookie下session的使用 session_start(); header('content-type:text/html;charset=utf-8'); $_SESSION['a']='a'; echo "<a href='dump-session.php?".session_name()."=".session_id()."' >查看session</a>";
此时访问后不会再有cookie存储,
而第二次访问时也可以看到,请求头中并没有带入cookie,而由于服务器并没有在浏览器cookie中检测到sessionid值 所以响应头中扔带着sessionid值。
当删除会话时:
<?php //销毁session步骤 //1、将$_SESSION清除 $_SESSION=[]; //2、将cookie中的sessionid删除 setcookie(); //3、销毁会话 session_destory session_id($_GET[session_name()]); session_start(); //将$_SESSION 数据清空 $_SESSION=[]; var_dump(session_id()); //销毁会话 session_destroy();
省去删掉cookie的步骤。
至此,session、cookie的介绍告一段落,下篇文章会自定义一下会话存储器,以存储到数据库中为例。