不同的请求方式,它们的请求格式可能是不一样的,请求格式就是我们所说的报文格式. 但是,通常来说一个HTTP请求报文由请求行(request line),请求头部(head),空行和请求数据4个部分组成,下图给出了请求报文的一般格式.
下面我们就来学习常用的GET,POST,PUT,DELETE四种请求方式的报文格式.
我们首先学习比较简单的GET和DELETE请求方式,对于DELETE和GET来说,由于它们的功能是删除和获取,因此,只要将URL构造为要处理的资源即可. 也就是说它们所有的参数附加在资源URL的最后,第一个参数前通过”?”符号连接,然后请求参数按照”参数名=参数值”的形式进行追加,每个参数之间用”&”连接. 例如 http://www.myhost.com/image?id=123&fotmat=png ,该URL的参数有id和format,它们的值分别为123和png,如果该请求是DELETE,那么将删除 http://www.myhost.com/image 下id为123,格式为png的图片,如果是GET,那么则是获取该图片. 需要注意的是,GET和DELETE的URL最大长度为1024字节,也就是1KB.
在浏览器中输入 http://www.devtf.cn/?p=909 ,这是开发技术前线第十九期周报的URL,得到的请求报文如下所示:
GET /?p=909 HTTP/1.1
Host: www.devtf.cn
Cache-Control: no-cache
根据上述的HTTP请求格式可知,第一行为请求行,代表请求方式是GET,子路径为/?p=909,也是表示参数p的值为909,HTTP版本为1.1 , 后两行是请求的HEADER区域,第一个请求头是主机地址,值www.devtf.cn. 另外还有一个Cache-Control的请求头,值为no-cache. GET,DELETE请求的所有参数都附加在URL链接中,因此,请求数据部分为空.
对于PUT和POST来说,他们的报文格式一般是表单形式,也就是说这两个请求方式的参数存储在报文的请求数据(报文主体)的位置上:
POST /api/feed/ HTTP/1.1
Accept-Encoding: gzip
Content-Length: 225873
Content-Type: multipart/form-data; boundary=OCqxMF6-JxtxoMDHmoG5W5eY9MGRsTBp
Host: www.myhost.com
Connection: Keep-Alive
--OCqxMF6-JxtxoMDHmoG5W5eY9MGRsTBp
Content-Disposition: form-data; name="username"
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Mr.Simple
--OCqxMF6-JxtxoMDHmoG5W5eY9MGRsTBp
Content-Disposition: form-data; name="images";
filename="/storage/emulated/0/Camera/jdimage/1xh0e3yyfmpr2e35tdowbavrx.jpg"
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
这里是图片的二进制数据,数据太长,在此省略
--OCqxMF6-JxtxoMDHmoG5W5eY9MGRsTBp--
上述请求的含义为向 www.myhost.com/api/feed/ 这个地址发送一个POST请求. 这个请求的数据格式(Content-Type)为multipart/form-data,报文的boundary值为OCqxMF6-JxtxoMDHmoG5W5eY9MGRsTBp. 该报文有两个参数,一个参数是文本类型的username参数,值为Mr.Simple,另一个是名为images的二进制参数,数据是一张图片的二进制数据,这里我们将图片的二进制数据省略了.
需要注意的是,一个参数是以两个横杠加上boundary开始的,然后是该参数的一些属性信息,例如参数名,格式等,然后加上一个空行,最后才是参数的值. 例如上述的username参数,完整的格式为:
--OCqxMF6-JxtxoMDHmoG5W5eY9MGRsTBp // 两个横杠加上boundary值
Content-Disposition: form-data; name="username" //这3个是请求参数的Header属性
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
//这里是一个不可省略的空行
Mr.Simple //这是参数值
POST与PUT都必须遵循这种的格式,每个参数以两个横杠和boundary分隔,参数header与参数值之间有一个空行. 另一个要注意的地方是,请求数据的最后是两个横杠+boundary值+两个横杠作为整个报文的结束符. 当手动构建POST请求报文时,这些格式就尤为重要,如果格式不正确,那么服务端将无法正确解析你的请求.
HTTP响应也由3个部分组成,分别是:状态行,消息报头,响应正文. 如下所示,HTTP响应的格式与请求的格式十分类似:
<状态行>
<响应报文header>
<空行>
[响应报文内容]
正如你所见,在响应中唯一真正的区别在于第一行中用状态信息代替了请求信息. 状态行(status line)通过提供一个状态码来说明所请求的资源情况.
状态行格式如下:
HTTP-Version Status-Code Reason-Phrase CRLF
其中,HTTP-Version表示服务器HTTP协议的版本; Status-Code表示服务器发回的响应状态代码; Reason-Phrase表示状态代码的文本描述. 状态代码由3位数字组成,第一个数字定义了响应的类别,且有5种可能取值,如下表所示.
取值范围 | 含义 |
---|---|
100~199 | 指示信息: 表示请求已接受,继续处理 |
200~299 | 请求成功: 表示请求已被成功接收,理解,接收 |
300~399 | 重定向: 要完成请求必须进行更进一步的操作 |
400~499 | 客户端错误: 请求有语法错误或请求无法实现 |
500~599 | 服务器端错误: 服务器未能实现合法的请求 |
常见状态代码,状态描述的说明如下.
例如,这是一个GET请求的Response返回示例:
HTTP/1.1 200 OK
Date: Sat, 31 Dec 2005 23:59:59 GMT
Content-Type: text/html;charset=
Content-Length: 122
<html>
<head>
<title>开发技术前线<title>
head>
<body>
<!-这里是Body -->
<body>
html>
该请求返回码为200,表示请求成功. 返回的数据类型为text/html,编码为ISO-8859-1,内容长度为122. 在一个空行之后就是返回的数据, 也就是一个html页面,也就是一个html页面. 客户端接受到这个返回结果之后,直接将结果展示到WebView上即可. 如果返回的是Json,XML格式的数据,那么,我们通常需要解析这些数据,并且将根据结果进行其他相应的处理.
请求头部由键值对组成,每行一对,关键字和值用英文冒号”:”分隔. HTTP规范定义了几种首部字段,应用程序也可以随意发明自己所用的首部. HTTP收不可以分为以下几类,如下表所示.
首部类型 | 作用 |
---|---|
通用首部 | 既可以出现在请求报文中,也可以出现在响应报文中 |
请求首部 | 提供更多有关请求的信息 |
响应首部 | 提供更多有关响应的信息 |
实体首部 | 描述主体的长度和内容,或者资源自身 |
扩展首部 | HTTP规范中没有定义的新首部 |
请求头部通知服务器关于客户端请求的信息,典型的请求头有: