关于HTTP协议和它的无状态性质
第一部分 HTTP协议的内容和特点
HTTP(HyperTextTransferProtocol)是超文本传输协议的缩写,它用于传送WWW方式的数据,关于HTTP协议的详细内容请参考RFC2616。HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的规范化工作正在进行之中,而且HTTP-NG(NextGenerationofHTTP)的建议已经提出。今天在实验室把相关的RFC文档仔细看了一下,对HTTP协议有了一个详细的认识,本文将做一个详细的介绍。
既然HTTP协议的目的在于支持超文本的传输,更加广义一些就是支持资源的传输,那么在客户端浏览器向HTTP服务器发送请求, 继而HTTP服务器将相应的资源发回给客户端这样一个过程中,无论对于客户端还是服务器,都没有必要记录这个过程,因为每一次请求和响应都是相对独立的, 就好像你在自动售货机前投下硬币购买商品一样,谁都不会也不需要记住这样一个交易过程。一般而言,一个URL对应着唯一的超文本,而HTTP服务器也绝对 公平公正,不管你是Michael,还是Jordon,它都会根据接收到的URL请求返回相同的超文本。正是因为这样的唯一性,使得记录用户的行为状态变 得毫无意义,所以,HTTP协议被设计为无状态的连接协议符合它本身的需求。
然而,随着时间的推移,人们发现静态的HTML着实无聊而乏味,增加动态生成的内容才会令Web应用程序变得更加有用。于是乎,HTML的语法在不断膨 胀,其中最重要的是增加了表单(Form);客户端也增加了诸如脚本处理、DOM处理等功能;对于服务器,则相应的出现了CGI(Common Gateway Interface)以处理包含表单提交在内的动态请求。在这种客户端与服务器进行动态交互的Web应用程序出现之后,HTTP无状态的特性严重阻碍了这 些应用程序的实现,毕竟交互是需要承前启后的,简单的购物车程序也要知道用户到底在之前选择了什么商品。于是,两种用于保持HTTP连接状态的技术就应运 而生了,一个是Cookie,而另一个则是Session。
Cookie是通过客户端保持状态的解决方案。从定义上来说,Cookie就是由服务器发给客户端的特殊信息,而这些信息以文本文件的方式存放在客户端, 然后客户端每次向服务器发送请求的时候都会带上这些特殊的信息。让我们说得更具体一些:当用户使用浏览器访问一个支持Cookie的网站的时候,用户会提 供包括用户名在内的个人信息并且提交至服务器;接着,服务器在向客户端回传相应的超文本的同时也会发回这些个人信息,当然这些信息并不是存放在HTTP响 应体(Response Body)中的,而是存放于HTTP响应头(Response Header);当客户端浏览器接收到来自服务器的响应之后,浏览器会将这些信息存放在一个统一的位置,对于Windows操作系统而言,我们可以从: [系统盘]:\Documents and Settings\[用户名]\Cookies目录中找到存储的Cookie;自此,客户端再向服务器发送请求的时候,都会把相应的Cookie再次发回 至服务器。而这次,Cookie信息则存放在HTTP请求头(Request Header)了。
有了Cookie这样的技术实现,服务器在接收到来自客户端浏览器的请求之后,就能够通过分析存放于请求头的Cookie得到客户端特有的信息,从而动态
生成与该客户端相对应的内容。通常,我们可以从很多网站的登录界面中看到“请记住我”这样的选项,如果你勾选了它之后再登录,那么在下一次访问该网站的时
候就不需要进行重复而繁琐的登录动作了,而这个功能就是通过Cookie实现的。
与Cookie相对的一个解决方案是Session,它是通过服务器来保持状态的。由于Session这个词汇包含的语义很多,因此需要在这里明确一下
Session的含义。首先,我们通常都会把Session翻译成会话,因此我们可以把客户端浏览器与服务器之间一系列交互的动作称为一个
Session。从这个语义出发,我们会提到Session持续的时间,会提到在Session过程中进行了什么操作等等;其次,Session指的是服
务器端为客户端所开辟的存储空间,在其中保存的信息就是用于保持状态。从这个语义出发,我们则会提到往Session中存放什么内容,如何根据键值从
Session中获取匹配的内容等。
要使用Session,第一步当然是创建Session了。那么Session在何时创建呢?当然还是在服务器端程序运行的过程中创建的,不同语言实现的
应用程序有不同创建Session的方法,而在Java中是通过调用HttpServletRequest的getSession方法(使用true作为
参数)创建的。在创建了Session的同时,服务器会为该Session生成唯一的Session
id,而这个Session
id在随后的请求中会被用来重新获得已经创建的Session;在Session被创建之后,就可以调用Session相关的方法往Session中增加
内容了,而这些内容只会保存在服务器中,发到客户端的只有Session
id;当客户端再次发送请求的时候,会将这个Session id带上,服务器接受到请求之后就会依据Session
id找到相应的Session,从而再次使用之。正式这样一个过程,用户的状态也就得以保持了。有关Session的内容还比较多,在以后的Post中,
我还将继续讲述。
另外,还有一种Application对象,它和Cookie及Session的区别主要如下图所示:
它的功能可以实现对所有用户的操作,用下面这个例子可以很容易的理解:
<%@ Page Language="C#" ContentType="text/html" ResponseEncoding="utf-8" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Application和Session的例子</title> </head> <body> <% int applicationCount=1; int sessionCount=1; //如果Application["ApplicationCount"]为空,即没有设置该名字的session if(Application["ApplicationCount"]==null) { Application["ApplicationCount"]=1; } else //否则取出以前的ApplicationCount ,并在上面加1 { applicationCount=(int)Application["ApplicationCount"]+1; Application["ApplicationCount"]=applicationCount; } //如果session["sessionCount"]为空,即没有设置该名字的session if(Session["SessionCount"]==null) { Session["SessionCount"]=1; } else { sessionCount=(int)Session["SessionCount"]+1; Session["SessionCount"]=sessionCount; } Response.Write("当前页面Application记录访问到了"+applicationCount+"次<br/>"); Response.Write("当前页面Session记录访问到了"+sessionCount+"次<br/>"); %> </body> </html> 这是一个Dreamweaver中的.aspx的文件,运行可知结果。

浙公网安备 33010602011771号