如果说HTTP是因特网的信使,那么HTTP报文就是它用来搬运东西的包裹了。
组成
HTTP报文是在HTTP应用程序之间发送的数据块。这些数据块以一些文本形式的元信息(meta-information)开头,这些信息描述了报文的内容及含义,后面跟着可选的数据部分。每一条报文都包含一条来自客户端的请求,或者一条来自服务器的响应。他们由三个部分组成:对报文描述的起始行(startline)、包含属性的首部(header)块,以及可选的、包含数据的主体(body)部分。起始行和首部就是由行分隔的ASCII文本,每行都以一个回车符(ASCII码13)和一个换行符(ASCII码10)组成行终止序列作为结束,这个终止序列可以写作CRLF。与起始行和首部不同的是,主体可以包含文本和二进制数据,也可以为空。
HTTP报文分为两类:请求报文和响应报文。请求报文格式如下:
<method><request-URL> <version>
<headers>
<entity-body>
响应报文格式:
<version><status> <reason-phrase>
<headers>
<entity-body>
例如:
现在对上面列出的一些基本HTTP报文结构进行讨论。
方法
下图是一张HTTP常用方法:
方法 | 描述 | 是否包含主体 |
GET | 从服务器获取一份文档 | 否 |
HEAD | 只从服务器获取文档的首部 | 否 |
POST | 想服务器发送需要处理的数据 | 是 |
PUT | 将请求的主体部分存储在服务器上 | 是 |
TRACE | 对可能经过代理服务器传送到服务器上去的报文进行追踪 | 否 |
OPTIONS | 决定可以在服务器上执行哪些方法 | 否 |
DELETE | 从服务器上删除一份文档 | 否 |
GET方法通常用于请求服务器发送某个资源,HTTP/1.1要求服务器实现此方法;
HEAD方法和GET行为很类似,但服务器在响应中只返回首部,不会返回实体部分。这就允许客户端在未获取实际资源的情况下,对资源的首部进行检查;
PUT方法会向服务器写入文档,就是让服务器用请求的主体部分来创建一个请求URL命名的新文档,或者,如果已存在,就用这个主体来替代它。此操作一般需要密码认证。
POST方法是向服务器输入数据的,然后由服务器将其发送到他要去的地方(比如,送到一个服务器网关程序中,然后由这个程序对其进行处理)。
TRACE方法,客户端发起一个请求时,这个请求可能要穿过防火墙、代理、网关或其他一些应用程序,每个中间节点都有可能修改原始的HTTP请求,行程最后一站的服务器(目的服务器)会弹回一条TRACE响应,并在响应主体中携带它收到的原始请求报文,这样客户端就可以查看在所有中间HTTP应用程序组成的请求/响应链上,原始报文是否修改或毁坏过。
OPTIONS方法一般用来询问服务器支持哪些方法,或者对某些特殊资源支持哪些方法。
DELETE方法请服务器删除请求URL所指定的资源。
扩展方法,指没有在HTTP/1.1规范中定义的方法,这样新的特性就不会使老的软件失效了。服务器会为它所管理的资源实现一些HTTP服务,这些方法为开发者提供一种扩展HTTP服务能力的手段。比如LOCK、MKCOL、COPY等。
状态码
状态码为客户端提供了一种理解事务处理结果的便捷方式,可分为五大类:
整体范围 | 已定义范围 | 分类 |
100~199 | 100~101 | 信息提示 |
200~299 | 200~206 | 成功 |
300~399 | 300~305 | 重定向 |
400~499 | 400~415 | 客户端错误 |
500~599 | 500~505 | 服务器错误 |
当前的HTTP版本只为每类状态定义了几个代码。随着协议的发展,HTTP规范中会正式的定义更多的状态码,如果收到了不认识的状态码,可能是有人将其作为当前协议的扩展定义的,可以根据范围,将它作为类别中的一个普通的成员来处理。
首部
首部和方法配合工作,共同决定了客户端和服务器能做什么事情。在请求和响应报文中都可以用首部来提供信息,有些首部是某种报文专用的,有些首部则更通用一些。可以将首部分为五个主要类型:通用首部、请求首部、响应首部、实体首部、扩展首部。
l 通用首部
客户端和服务器都可以使用的通用首部,最常见的就是Date:Tue, 3 Oct 2014 02:02:22 GMT。其余的首部就不再列出,HTTP/1.0引入了第一个允许HTTP应用程序缓存对象本地副本的首部,这样就不需要总是直接从源服务器获取了,如Cache-Control。
l 请求首部
是请求报文特有的,他们为服务器提供了一些额外信息,比如客户端希望接受什么类型的数据,服务器可根据请求首部为客户端提供更好的响应。下面列出几种比较重要的请求首部:
Accept首部:将客户端的喜好和能力告知服务器;
条件请求首部:为请求加上限制,要求服务器在对请求响应之前,确保限制条件为真;
安全请求首部:要求客户端在获取特定资源之前,先对自身进行认证,确保事务安全;
代理请求首部:因代理的普遍使用,定义了几个首部来协助其更好的工作;
l 响应首部
和请求首部异曲同工,有协商首部、安全响应首部等,具体可查询,就不再列出。
l 实体首部
由于请求报文和响应报文中都可能包含实体部分,所以在这两种类型的报文中都可能出现实体首部,实体首部可以告知报文的接受者他在对什么进行处理。下面是两种实体的信息性首部:
首部 | 描述 |
Allow | 列出了可以对此实体执行的请求方法 |
Location | 告知客户端实体实际上位于何处;用于将接收端定向到资源的位置上去 |
内容首部提供了与实体内容有关的特定信息,比如类型、尺寸等,比如浏览器可以通过查看返回的内容类型,得知如何显示对象:
首部 | 描述 |
Content-Base | 解析主体中的相对URL时使用的基础URL |
Content-Encoding | 对主体执行的任意编码方式 |
Content-Language | 理解主体时最适宜使用的自然语言 |
Content-Length | 主体的长度或尺寸 |
Content-Location | 资源实际所处的位置 |
Content-MD5 | 主体的MD5校验 |
Content-Range | 在整个资源中此实体表示的字节范围 |
Content-Type | 这个主体的对象模型 |
通用的缓存首部说明了如何或什么时候进行缓存。实体的缓存首部提供了与被缓存实体有关的信息——比如,验证已缓存资源是否是否仍然有效所需的信息等。
首部 | 描述 |
ETag | 与此实体有关的实体标记 |
Expires | 实体不在有效,要从原始的源端再次获取此实体的日期和时间 |
Last-Modified | 这个实体最后一次被修改的日期和时间 |