欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Cookie与Session简介

程序员文章站 2022-03-16 22:41:24
Cookie与Session简介 本章介绍重点: 本章重点为大家介绍在Web开发过程当中经常会使用到的Cookie与Session的概念,它们的使用方法和应用场景,以及它们的优点与局限等等。深刻理解与掌握它们的用法,可以更好的帮助我们开发出正确可用的产品。 我们为什么需要Cookie与Session ......

Cookie与Session简介

本章介绍重点:

本章重点为大家介绍在Web开发过程当中经常会使用到的Cookie与Session的概念,它们的使用方法和应用场景,以及它们的优点与局限等等。深刻理解与掌握它们的用法,可以更好的帮助我们开发出正确可用的产品。

 

 

我们为什么需要Cookie与Session:

在开始本章程的介绍之前,我们有必要要问自己一个问题,我们为什么需要Cookie与Session?它们可以帮助我们解决什么问题?

让我们先来了解了解我们经常使用的HTTP协议是什么:HTTP是一个属于应用层的面相对象的应用协议,它具有以下五个特点:

  • 支持客户端<->服务器服务
  • 简单快速
  • 灵活
  • 无连接
  • 无状态

如何理解HTTP的无状态特性?用当下流行的一句话来描述就是“人生若只如初见”。HTTP协议处理事务请求没有记忆能力,对同一个URL的请求没有上下文的关系,你所发出的每一次HTTP请求都是独立的,它的执行情况与响应的结果不会受到之前的HTTP请求的影响,当然它也不会干扰影响后续的HTTP请求与响应,处理HTTP请求的服务器没有保存客户端的状态

可以设想一下,假如基于这些特性而不做任何的特殊处理与改进,我们访问网络站点时会是怎样的体验?拿网购来说吧。当我们访问某电子商城的时候,提示需要输入用户名以及密码,我们按要求填写所需信息成功登陆,琳琅满目的商品展示在我们的眼前,我看上了一款最新的电子产品,打算点进去看看详细介绍,可接下的情况却让我们大跌眼镜,由于服务器没有我们的登陆状态,网站竟要求我重新输入用户名跟密码?这将会是一个多么糟糕的用户体验。

很明显,HTTP的这种无状态的特性严重的阻碍了我们与服务器的交互,于是两种用于保持HTTP连接状态的技术就应用而生了:Cookie与Session,这也是我们本章的介绍重点。

 

 

Cookie:

 Cookie是什么?

翻阅*以及百度百科,我们不难发现,Cookie 是在 HTTP 协议下,服务器或脚本用以维护客户工作站信息的一种方式。它是由 Web 服务器保存在用户浏览器(客户端)上的小文本文件,可以用于记录用户的活动或者是与记录与状态相关的信息。Cookie是由W3C组织提出,最早由NetScape公司开发实现,现已经成为了一种标准,主流浏览器都支持Cookie机制。

Cookie的工作机制可以参见下面的图示:

Cookie与Session简介

正如前面所说,Cookie保存在客户端电脑,不同的浏览器,存放的路径可能有所不同,如下列举几个常见主流浏览器的存放位置:

  • IE存放位置:C:\Users\{$UserName}\AppData\Roaming\Microsoft\Windows\Cookies\xxx.txt
  • FireFox存放位置:C:\Users\{$UserName}\AppData\Roaming\Mozilla\Firefox\Profiles\{$xxx.default}\cookies.sqlite
  • Chrome存放位置:C:\Users\{$UserName}\AppData\Local\Google\Chrome\User Data\Default\Cookies

注意:IE浏览器中,IE将各个站点的Cookie分别保存为一个txt纯文本文件;而Firefox和Chrome是将所有的Cookie都保存在一个文件中,该文件的格式为SQLite3数据库格式的文件。

 

 Cookie的属性:

Cookie的常用属性可以参阅下列表格:

Cookie与Session简介

 

 Cookie的Server Side操作:

创建一个新的Cookie,我们可以通过以下的代码来实现:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	Cookie myCookie = new Cookie("username", "WebOpenShare");
	myCookie.setMaxAge(300);
	myCookie.setDomain("www.webopenshare.com");
	myCookie.setPath("/");
	myCookie.setSecure(false);
	response.addCookie(myCookie);
}

运行上述的代码,我们便可以得到一个名为"username",其对应的值为"WepOpenShare"。(如果你是本地运行Tomcat服务器,请记得修改你电脑hosts文件)

Cookie与Session简介

 

Cookie对象没有提供直接修改其属性的方法,要修改原有Cookie的值,我们只能够通过创建同名的Cookie并添加到response中覆盖掉原Cookie的设置,如下所示:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	// ...
	Cookie myModifiedCookie = new Cookie("username", "MyWebOpenShare");
	myModifiedCookie.setMaxAge(600);
	myModifiedCookie.setDomain("www.webopenshare.com");
	myModifiedCookie.setPath("/");
	myModifiedCookie.setSecure(false);
	response.addCookie(myModifiedCookie);
}

Cookie与Session简介

同样的,Cookie对象也没有提供直接删除某一个Cookie的操作方法,想要删除某一个Cookie,我们只能够通过新建一个maxAge为0的同名Cookie,把它添加到response中删除原先的Cookie,具体如下代码所示:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	// ...
	Cookie deleted = new Cookie("username", "MyWebOpenShare");
	deleted.setMaxAge(0);
	deleted.setDomain("www.webopenshare.com");
	deleted.setPath("/");
	deleted.setSecure(false);
	response.addCookie(deleted);
}

注意:修改跟删除某一个Cookie时,我们要通过创建一个同名Cookie来进行覆盖,对于这一个同名Cookie,除了它的value跟maxAge属性可以不同,其余的所有属性必须跟要修改的Cookie保持一致,否则将会操作失败。

 

 Cookie的Client Side操作:

我们知道Cookie是保存在客户端的,那么我们可不可以通过一些脚本语言,例如JavaScript在浏览器中操作Cookie呢?如果有,我们可不可以像在Server Side操作Cookie一样,对Cookie进行读写/修改甚至是删除的操作呢?

可以肯定的是,我们可以通过脚本在浏览器中操作Cookie,但是出于安全性的考虑,它所允许的操作非常有限,仅限于读取当前域名下的Cookie,不可以修改或者删除Cookie。通过下面的代码我们就可以读取出当前Domain下的Cookies.

<script>document.write(document.cookie);</script>

 

 Cookie应该存放什么值:

前面的介绍当中,我们提及Cookie存放在客户端的文件上,如果客户端被入侵,那么这些Cookie文件存在被盗的潜在危险;另一方面,我们都知道,HTTP协议采用的是明文传输的方式,如果有人监听或者是截取了我们的请求,那么我们通过Cookie传送给服务器的信息就就全部曝露在入侵者面前。因此,存放在Cookie里面的值应当尽量避免个人敏感信息,如果非要存放敏感关键信息的时候,也要先经过加密处理之后再存放。

 

 

Session:

Session是什么?

Session是另外一种用户保持HTTP连接状态的解决方案,与Cookie不同,Session存放于服务器内存当中,服务器采用了一种类似于散列表(Hashtable)的形式来存放Session对象信息。

Session保存在服务器上,所以它会消耗服务器的资源,因此,我们不应该在Session里面存放太多太过复杂厚重的对象跟信息,在高并发的情况之下,这样做很容易会使得服务器内存溢出使得程序异常或者最终宕机。

Session的机制:

Session的机制,可以参见下图:

Cookie与Session简介

 

Session何时创建?

Session何时被创建呢?是不是我们访问服务器就会创建一个Session呢?答案是否定的,只有我们在程序中调用到Session的时候,服务器才会帮我们创建Session对象。例如在Servlet当中,当我们调用request.getSession()的方法时,服务器就会创建一个Session对象。但是细心的朋友可能会发现,当我访问某一个JSP页面的时候,也会有Session对象生成,此时我并没有在Servlet或者是JSP当中显式的使用任何的request.getSession()方法。这里我特别强调的是显式这个词语,其实当我们访问JSP的时候,JSP编译成Servlet的时候默认会帮我们添加这样的代码:HttpSession session = request.getSession(),这也是为什么我们可以什么都不做,就直接在JSP页面当中使用session.getAttribute()或者是其它的操作。

 

Session何时销毁?

前面谈了Session的创建,接下来我们来看看Session何时被销毁?当然,关闭服务器可以保证所有的Session被销毁。那关闭浏览器呢?很多人有一个误解,觉得只要我关闭了浏览器,Session就销毁了。其实这种理解是不全面的,我们知道,Session是由服务器创建并维护的,因此销毁与否须由服务器来完成,单纯关闭端浏览器并不会触发销毁内存的动作,如果我们重新打开浏览器,并向服务器发送之前的Session ID,是可以找回之前的Session的。只有在关闭浏览器的同时触发一条服务器请求,告诉服务器销毁掉内存,那才可以做到这样的效果。

恰恰是由于关闭浏览器并不能销毁内存,出于安全性的考量,我们需要为Session来设置一个有效期,当一次访问距离上次的请求超过这个有效期的话,那之前的Session就会销毁失效。

 

Cookie被禁用时?

Session的工作机制,默认情况下是需要浏览器的Cookie来配合工作的。当服务器创建一个全新的Session之后,会向浏览器发送一个Session ID的信息,通常是以Cookie的形式返回给客户端,在接下来的请求中,客户端便会自动在请求当中携带上这个Session ID的参数,服务器根据传递上来的Session ID直接从服务器中查找返回之前的Session对象。但是如果客户端禁用Cookie呢?

由于Cookie可以被人为的禁止,必须有其它机制以便在Cookie被禁止时仍然能够把Session ID传递回服务器。经常被使用的一种技术叫做URL重写,就是把Session ID直接附加在URL路径的后面,附加方式也有两种,一种是作为URL路径的附加信息,表现形式为http://${domain}:${port}/${uri};SESSIONID=xxxxxxxxxxx;另一种是作为查询字符串附加在URL后面,表现形式为http://${domain}:${port}/${uri}?SESSIONID=xxxxxxxxxxx

 

Session常用方法:

Session的常用方法总结如下表所示:

Cookie与Session简介

 

抛出引子:

Session不同的应用之*享数据呢?请关注我们,在后续章节中我们会为您揭秘。

 

我要小额赞助,鼓励作者写出更好的文章:

Cookie与Session简介