浅析HTTP协议之请求与响应
1. 简介
HTTP协议是基于请求响应模式的,即客户端发起请求,服务器端响应。如图:
也就是说,要获取服务器端的响应,我们必须由客户端发起请求,否则服务器端无法主动将消息推送给客户端。
HTTP是无状态协议,同一个端两次发起的请求是没有对应关系的。
一般HTTP的工作流程有以下几个步骤:
- 客户机与服务器需要建立连接。如我们单击页面中的一个超链接,HTTP开始工作,建立与服务器间的连接。
- 建立连接后,客户端发送一个请求给服务器,请求格式包括为:统一资源标识符(URL)、协议版本号,MIME信息(包括请求修饰符、客户机信息和可能的内容)。
- 服务器接到请求后处理,并传送响应信息,其格式为一个状态行(包括信息的协议版本号、一个成功或错误的代码),MIME信息(包括服务器信息、实体信息和可能的内容)。
- 客户端接收服务器所返回的响应信息,通过浏览器显示出来,然后断开客户端与服务器连接。
2. HTTP协议之请求
HTTP请求由三部分组成,分别是:请求行、消息报头、请求正文。
HTTP消息由客户端到服务器的请求和服务器到客户端的响应组成。请求消息和响应消息都是由开始行(对于请求消息,开始行就是请求行,对于响应消息,开始行就是状态行),消息报头(可选),空行(只有CRLF的行),消息正文(可选)组成。
请求行
请求行格式:方法 [空格] 请求URI [空格] 版本号 [回车换行],如:
GET /Servlet/login.do HTTP/1.1
POST /Servlet/do_login.do HTTP/1.1
消息报头
HTTP消息报头包括普通报头、请求报头、响应报头、实体报头。
每一个报头域都是由名字+“:”+空格+值 组成,消息报头域的名字是大小写无关的。
普通报头示例:
Connection: Keep-Alive(CRLF)
Cache-Control: no-cache(CRLF)
Cache-Control用于指定缓存指令,no-cache用于指示请求或响应消息不能缓存。
Connection允许发送指定连接的选项,keep-alive指定连接是连续的。
请求报头示例:
Accept: image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*(CRLF)
Referer: http://localhost:8080/Servlet/login.do(CRLF)
Accept-Language: zh-CN(CRLF)
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; Tablet PC 2.0)(CRLF)
Accept-Encoding: gzip, deflate(CRLF)
Host: localhost:8080(CRLF)
Accept用于指定客户端接受哪些类型的信息。
Accept-Language类似于Accept,但是它是用于指定一种自然语言。如果请求消息中没有设置这个报头域,服务器假定客户端对各种语言都可以接受。
Accept-Encoding也类似于Accept,但是它是用于指定可接受的内容编码。
Refer用于指明来源,即上一页的地址。
User-Agent允许客户端将它的操作系统、浏览器和其它属性告诉服务器。我们上网登陆一些论坛的时候,往往会看到一些欢迎信息,其中列出了你的操作系统的名称和版本,你所使用的浏览器的名称和版本,这往往让很多人感到很神奇,实际上,服务器应用程序就是从User-Agent这个请求报头域中获取到这些信息。
Host用于指定被请求资源的Internet主机和端口号,它通常从HTTP URL中提取出来的。
实体报头示例:
Content-Type: application/x-www-form-urlencoded(CRLF)
Content-Length: 29(CRLF)
Content-Type用于指明发送给接收者的实体正文的媒体类型。
Content-Length用于指明实体正文的长度,以字节方式存储的十进制数字来表示。
完整的报头示例:
Accept: image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*(CRLF)
Referer: http://localhost:8080/Servlet/login.do(CRLF)
Accept-Language: zh-CN(CRLF)
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; Tablet PC 2.0)(CRLF)
Content-Type: application/x-www-form-urlencoded(CRLF)
Accept-Encoding: gzip, deflate(CRLF)
Host: localhost:8080(CRLF)
Content-Length: 29(CRLF)
Connection: Keep-Alive(CRLF)
Cache-Control: no-cache(CRLF)
(CRLF)
请求正文
请求头(消息报文)和请求正文之间是一个空行,这个行非常重要,它表示请求头已经结束,接下来的是请求正文。请求正文中可以包含客户提交的查询字符串信息,如:
username=test&password=123456
3. HTTP协议之响应
HTTP的响应消息也是由三个部分组成,分别是:状态行、消息报头、响应正文。
状态行
状态行格式:协议版本号 [空格] 响应状态码 [空格] 状态码文本描述 [回车换行],如:
HTTP/1.1 200 OK
消息状态码通常有五种类别:
1xx:指示信息,表示请求已接收,继续处理。
2xx:成功,表示请求已被成功接收、理解、接受。
3xx:重定向,要完成请求必须进行更进一步的操作。
4xx:客户端错误,请求有语法错误或请求资源不存在等。
5xx:服务器端错误,服务器未能实现合法的请求。
常见的状态码:
状态码 | 描述文本 | 说明 |
---|---|---|
200 | OK | 客户端请求成功 |
400 | Bad Request | 客户端请求有语法错误,不能被服务器所理解 |
401 | Unauthorized | 请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用 |
403 | Forbidden | 服务器收到请求,但是拒绝提供服务 |
404 | Not Found | 请求资源不存在,如:输入了错误的URL |
500 | Internal Server Error | 服务器发生不可预期的错误 |
503 | Server Unavailable | 服务器当前不能处理客户端的请求,一段时间后可能恢复正常 |
消息报头
普通报头示例:
Date: Tue, 14 Jul 2015 02:00:15 GMT(CRLF)
Transfer-Encoding: chunked(CRLF)
Date用于表示消息产生的日期和时间。
Transfer-Encoding: chunked表示输出的内容长度不能确定,普通的静态页面、图片之类的基本上都用不到这个,但动态页面就有可能会用到。
响应报头示例:
Server: Apache-Coyote/1.1(CRLF)
Server包含了服务器用来处理请求的软件信息,Apache-Coyote/1.1表明了服务器名称与版本号。
实体报头示例:
Content-Type: text/html;charset=gbk(CRLF)
Content-Type指明发送给接收者的实体正文的媒体类型,text/html;charset=gbk表示正文是一个html文档,采用gbk编码。
报头完整示例:
Server: Apache-Coyote/1.1(CRLF)
Content-Type: text/html;charset=gbk(CRLF)
Transfer-Encoding: chunked(CRLF)
Date: Tue, 14 Jul 2015 02:00:15 GMT(CRLF)
(CRLF)
响应正文
响应头和响应正文之间也有一个空行,它表示响应头已经结束,接下来的是响应正文。响应正文中包含服务器响应返回客户端的消息,如:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD><TITLE>A Servlet</TITLE></HEAD>
<BODY>
<h1>登录处理</h1>登录成功 </BODY>
</HTML>