- Java Web开发技术教程
- 李西明 陈立为 邵艳玲主编
- 3453字
- 2025-04-01 14:59:53
1.3 HTTP
HTTP可用来定义Web客户端如何向Web服务器请求Web页面,以及服务器如何把Web页面传送给客户端。
1.3.1 HTTP的主要特点
(1)简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定的客户与服务器联系的类型都不相同。由于HTTP简单,HTTP服务器的程序规模小,因而通信速度很快。
(2)灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
(3)无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即会断开连接。采用这种方式可以节省传输时间。
(4)无状态:HTTP是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另外,在服务器不需要先前信息时它的应答就比较快。HTTP协议支持浏览器/服务器(Browser/Server,B/S)和客户端/服务器(Client/Server,C/S)两种模式。
1.3.2 HTTP常用的请求方法
HTTP常用的两种请求方法是GET方法和POST方法。GET和POST的区别如下。
(1)通过GET方法提交的数据会放在URL之后,以“?”分割URL和传输数据,参数之间以“&”相连,如“EditPosts.aspx?name=test1&id=123456”。POST方法则是把提交的数据放在HTTP包的Body中。
(2)通过GET方法提交的数据大小有限制(因为浏览器对URL的长度有限制),而通过POST方法提交的数据大小没有限制。
(3)GET方法需要使用Request.QueryString来取得变量的值,而POST方法则可通过Request.Form来获取变量的值。
(4)通过GET方法提交数据会带来安全问题,例如,一个登录页面通过GET方法提交数据时,用户名和密码将出现在URL上,如果页面可以被缓存或者其他人可以访问这台机器,他人就可以从历史记录中获得该用户的账号和密码。
1.3.3 HTTP的状态
HTTP是一种不保存状态的(即无状态的)协议。也就是说,HTTP不具有保存之前发送过的请求或者响应的功能。在使用HTTP的时候,每当有新的请求就会有对应的新响应产生。这样就会产生一个问题,例如,访问某系统的时候,由于HTTP是不保存状态的,也就是说在第一个页面登录之后,再到其他页面(如由网上选课页面到课表页面)的时候,是需要重新登录一遍的,这样显然是不合理的。而且在实际操作当中并没有每到一个页面都要重新登录一遍。这是如何完成的呢?其实这里引入了Cookie对象对登录的信息进行保存,而且值得注意的是,在HTTP的1.1版本中有持久连接。
1.持久连接与管线化
假设这样一个场景,小明打电话给小强,让小强帮他带一份饭回来。如果没有建立持久连接,则拨通/挂掉电话就会建立/断开连接,每次说话都相当于请求/响应。
从图1.8中可以看到,如果每次发送或响应请求都需要建立连接,这样就会消耗很多的时间。看起来这个例子里面的消耗不是很多,但是当访问量达到百万级、千万级的时候,服务器中的资源就会浪费很多。所以为了解决上述问题,HTTP 1.1版本中就提出了建立持久连接。持久连接的特点是,只要任意一端没有明确提出断开连接,就会一直保持TCP的连接状态。
此时,发出请求和响应请求的速度明显加快了,但是这样还不够。从图1.9中可以看到,当小明(客户端)发出一个请求的时候,必须等待小强(服务器端)对这个请求响应之后,才能对下一个请求进行发送。
小明在等待小强响应的过程中可能还会发出其他的请求。为了解决这一问题,我们可以用一种管线化的方式发送请求。再用之前的例子来说明。不管小强有没有对小明刚刚的请求进行响应,只要他们之间建立了连接,小明就可以对小强发出请求。实现管线化之后的例子如图1.10所示。

图1.8 没有持久连接

图1.9 有持久连接

图1.10 用管线化的方式发送请求
2.Cookie的状态管理
前面提到过,HTTP是无状态的协议,不管之前发生过什么请求或响应,都是不会保存的。也就是说每次的页面跳转都要重新进行用户登录的操作,这样就会浪费很多资源,并且十分麻烦。所以就引入了Cookie对象,用来保存这些用户的状态信息。
第一次发送请求如图1.11所示,客户端发送的请求是没有Cookie信息的,当服务器端进行响应时,服务器就会在响应请求中包含一个Cookie信息,并且在响应行里标明信息,让客户端对Cookie信息进行保存。
当客户端发送第二次请求的时候(见图1.12),就会找到刚刚保存的Cookie,并在请求行里标明Cookie信息,把Cookie随着请求一起发送到服务器端。服务器端解析Cookie信息,就知道这是谁发送的请求。

图1.11 第一次发送请求

图1.12 第二次发送请求
1.3.4 HTTP工作原理
HTTP采用了请求/响应模型。客户端向服务器发送一个请求报文,请求报文中包含请求的方法、URL、协议版本、请求头部和请求数据。服务器以一个状态行作为响应,响应内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据。
HTTP请求/响应的步骤如下。
(1)客户端连接到Web服务器
一个HTTP客户端通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接。例如,http://www.baidu.com。
(2)发送HTTP请求
通过TCP套接字,客户端向Web服务器发送一个文本的请求报文。一个请求报文由请求行、请求头部、空行和请求数据4部分组成。
(3)服务器接受请求并返回HTTP响应
Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应报文由状态行、响应头部、空行和响应数据4部分组成。
(4)释放/保持TCP连接
若connection(连接)模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection(连接)模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求。
(5)客户端浏览器解析HTML内容
客户端浏览器首先解析状态行,查看标明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示数据。
1.3.5 HTTP报文
用于HTTP交互的信息可称为HTTP报文。请求端(客户端)的HTTP报文叫作请求报文,响应端(服务器端)的叫作响应报文。而报文也可以分为报文首部和报文主体两块,如图1.13所示,报文首部和报文主体中间有一个空行。

图1.13 HTTP报文的格式
1.请求报文
HTTP请求报文的首部也可以继续细分成请求头和请求行,如图1.14所示。

图1.14 HTTP请求报文
(1)GET请求例子,使用Charles抓取的请求:
GET /562f25980001b1b106000338.jpg HTTP/ 1.1 Host img.mukewang.com User-Agent Mozilla/5.0(Windows NT10.0; WOW64) AppleWebKit/537.36(KHTML.like Gecko) Chrome/51.0.2704.106 Safari/537.36 Accept image/webp.image/**/; q=0.8 Referer http://www.imooc.com/ Accept-Encoding gzip, deflate, sdch
第一部分:请求行,用来说明请求类型、要访问的资源以及所使用的HTTP版本。GET说明请求类型为GET,“/562f25980001b1b106000338.jpg”为要访问的资源,该行的最后一部分说明使用的是HTTP 1.1版本。
第二部分:请求头部,紧接着请求行(即第一行)之后的部分,用来说明服务器要使用的附加信息。从第二行起为请求头部,Host将指出请求的目的地“User-Agent”,服务器端和客户端脚本都能访问它,它是浏览器类型检测逻辑的重要基础。该信息由浏览器来定义,并且在每个请求中自动发送。
第三部分:空行,请求头部后面的空行是必需的,即使第四部分的请求数据为空,也必须有空行。
第四部分:请求数据(也叫作主体),可以添加任意的其他数据。这个例子的请求数据为空。
(2)POST请求例子,使用Charles抓取的请求:
POST/HTTP/1.1 Host:www.wrox.com User-Agent:Mozilla/4.0(compatible; MSIE6.0; Windows NT5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR3.5.21022) Content-Type:application/x-www-form-urlenco ded Content-Length:40 Connection:Keep-Alive name =Professional%20Ajax&publisher=Wiley
第一部分:请求行,第1行说明了是POST请求,以及HTTP 1.1版本。
第二部分:请求头部,第2~6行。
第三部分:空行,第7行。
第四部分:请求数据,第8行。
2.响应报文
一般情况下,服务器接收并处理客户端发过来的请求后会返回一个HTTP的响应信息。
HTTP响应也由4个部分组成:状态行、消息报头、空行和响应正文,如图1.15所示。

图1.15 HTTP响应报文
第一部分:状态行,由HTTP版本号、状态码、状态消息三部分组成。在第一行中,HTTP/1.1表明HTTP版本为1.1,状态码为200,状态消息为OK。
第二部分:消息报头,用来说明客户端要使用的一些附加信息。第二行和第三行为消息报头,Date是生成响应的日期和时间,Content-Type指定了MIME类型的HTML(text/html),编码类型是UTF-8。
第三部分:空行,消息报头后面的空行是必需的。
第四部分:响应正文,服务器返回给客户端的文本信息。
1.3.6 HTTP状态码
1.状态码的种类
状态代码由三位数字组成,第一个数字定义了响应的类别。状态代码分为以下几种。
(1)1xx:指示信息,表示请求已接收,继续处理。
(2)2xx:成功,表示请求已被成功接收、理解、接受。
(3)3xx:重定向,表示完成请求必须进行更进一步的操作。
(4)4xx:客户端错误,表示请求有语法错误或请求无法实现。
(5)5xx:服务器端错误,表示服务器未能实现合法的请求。
2.常见状态码
(1)200 OK:客户端请求成功。
(2)400 Bad Request:客户端请求有语法错误,不能被服务器所理解。
(3)401 Unauthorized:请求未经授权,这个状态码必须与WWW-Authenticate报头域一起使用。
(4)403 Forbidden:服务器收到请求,但是拒绝提供服务。
(5)404 Not Found:请求资源不存在,如输入了错误的URL。
(6)500 Internal Server Error:服务器发生不可预期的错误。
(7)503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常。