HTTP(三)报文
报文流
HTTP 报文是在HTTP 应用程序之间发送的数据块。这些数据块以一些文本形式的元信息(meta-information)开头,这些信息描述了报文的内容及含义,后面跟着可选的数据部分。这些报文在客户端、服务器和代理之间流动。术语“流入”、“流出”、“上游”及“下游”都是用来描述报文方向的。
报文流入源端服务器
HTTP 使用术语流入(inbound)和流出(outbound)来描述事务处理(transaction)的方向。
报文向下游流动
不管是请求报文还是响应报文,所有报文都会向下游(downstream) 流动。所有报文的发送者都在接收者的上游。
报文的组成部分
每条报文都包含一条来自客户端的请求,或者一条来自服务器的响应。它们由三个部分组成:对报文进行描述的起始行(start line)、包含属性的首部块(header),以及可选的、包含数据的主体(body)部分。
起始行和首部就是由行分隔的ASCII 文本。每行都以一个由两个字符组成的行终止序列作为结束,其中包括一个回车符(ASCII 码13)和一个换行符(ASCII 码10)。这个行终止序列可以写做CRLF。
实体的主体或报文的主体(或者就称为主体)是一个可选的数据块。与起始行和首部不同的是,主体中可以包含文本或二进制数据,也可以为空。
报文的语法
所有的HTTP 报文都可以分为两类: 请求报文(request message) 和响应报文(response message)。
请求报文会向Web 服务器请求一个动作。响应报文会将请求的结果返回给客户端。请求和响应报文的基本报文结构相同。
请求报文的格式:
<method> <request-URL> <version> <headers> <entity-body>
响应报文的格式:
<version> <status> <reason-phrase> <headers> <entity-body>
- 方法(method):
客户端希望服务器对资源执行的动作。是一个单独的词,比如GET、HEAD 或POST。
- 请求URL(request-URL):
命名了所请求资源,或者URL 路径组件的完整URL。 - 版本(version):
报文所使用的HTTP 版本
HTTP/<major>.<minor>
其中主要版本号(major)和次要版本号(minor)都是整数。
- 状态码(status-code):
这三位数字描述了请求过程中所发生的情况。每个状态码的第一位数字都用于描述状态的一般类别(“成功”、“出错”等)
- 原因短语(reason-phrase):
数字状态码的可读版本 - 首部(header):
可以有零个或多个首部,每个首部都包含一个名字,后面跟着一个冒号(:),然后是一个可选的空格,接着是一个值,最后是一个CRLF。首部是由一个空行
(CRLF)结束的,表示了首部列表的结束和实体主体部分的开始。有些HTTP 版本,比如HTTP/1.1,要求有效的请求或响应报文中必须包含特定的首部。
- 实体的主体部分(entity-body):
实体的主体部分包含一个由任意数据组成的数据块。
起始行
所有的HTTP 报文都以一个起始行作为开始。请求报文的起始行说明了要做些什么。响应报文的起始行说明发生了什么。
1.请求行
请求报文的起始行,或称为请求行,包含了一个方法和一个请求URL,这个方法描述了服务器应该执行的操作,请求URL描述了要对哪个资源执行这个方法。请求行中还包含HTTP 的版本。所有这些字段都由空格符分隔。
2.响应行
响应报文的起始行,或称为响应行,包含了响应报文使用的HTTP 版本、数字状态码,以及描述操作状态的文本形式的原因短语。所有这些字段都由空格符进行分隔。
3.方法
方法用来告知服务器要做些什么。
HTTP 规范中定义了一组常用的请求方法。比如,GET 方法负责从服务器获取一个文档,POST 方法会向服务器发送需要处理的数据,OPTIONS 方法用于确定Web服务器的一般功能,或者Web 服务器处理特定资源的能力。
服务器还可以实现自己的请求方法,被称为扩展方法。
4.状态码
状态码则用来告诉客户端,发生了什么事情。
200 到299 之间的状态码表示成功。300 到399 之间的代码表示资源已经被移走了。400 到499 之间的代码表示客户端的请求出错了。500 到599 之间的代码表示服务器出错了。
如果收到了不认识的状态码,可能是有人将其作为当前协议的扩展定义的。
5.原因短语
它为状态码提供了文本形式的解释。
6.版本号
版本号会以HTTP/x.y 的形式出现在请求和响应报文的起始行中。为HTTP 应用程序提供了一种将自己所遵循的协议版本告知对方的方式。
首部
header是零个、一个或多个名值对。
1.首部分类
- 通用首部
既可以出现在请求报文中,也可以出现在响应报文中。 - 请求首部
提供更多有关请求的信息。 - 响应首部
提供更多有关响应的信息。 - 实体首部
描述主体的长度和内容,或者资源自身。 - 扩展首部
规范中没有定义的新首部。
每个HTTP 首部都有一种简单的语法:名字后面跟着冒号( :),然后跟上可选的空格,再跟上字段值,最后是一个CRLF。
2.首部延续行
将长的首部行分为多行可以提高可读性,多出来的每行前面至少要有一个空格或制表符(tab)。
HTTP/1.0 200 OK
Content-Type: image/gif
Content-Length: 8572
Server: Test Server
Version 1.0
在这个例子中,响应报文里包含了一个Server 首部,其值被划分成了多个延续行。该首部的完整值为Test Server Version 1.0。
实体的主体部分
实体的主体是HTTP 报文的负荷。就是HTTP 要传输的内容。
方法
安全方法
HTTP 定义了一组被称为安全方法的方法。GET 方法和HEAD 方法都被认为是安全的,这就意味着使用GET 或HEAD 方法的HTTP 请求都不会产生什么动作。不产生动作,在这里意味着HTTP 请求不会在服务器上产生什么结果。
GET
GET 是最常用的方法。通常用于请求服务器发送某个资源。
HEAD
HEAD 方法与GET 方法的行为很类似,但服务器在响应中只返回首部。不会返回实体的主体部分。这就允许客户端在未获取实际资源的情况下,对资源的首部进行检查。使用HEAD,可以:
- 在不获取资源的情• 况下了解资源的情况(比如,判断其类型);
- 通过查看响应中的状态码,看看某个对象是否存在;
- 通过查看首部,测试资源是否被修改了。
服务器开发者必须确保返回的首部与GET 请求所返回的首部完全相同。遵循HTTP/1.1 规范,就必须实现HEAD 方法。
PUT
PUT 方法会向服务器写入文档。有些发布系统允许用户创建Web 页面,并用PUT 直接将其安装到Web 服务器上去。
PUT 方法的语义就是让服务器用请求的主体部分来创建一个由所请求的URL 命名的新文档,或者,如果那个URL 已经存在的话,就用这个主体来替代它。
POST
POST 方法是用来向服务器输入数据。
TRACE
客户端发起一个请求时,这个请求可能要穿过防火墙、代理、网关或其他一些应用程序。每个中间节点都可能会修改原始的HTTP 请求。TRACE 方法允许客户端在最终将请求发送给服务器时,看看它变成了什么样子。
OPTIONS
OPTIONS 方法请求Web 服务器告知其支持的各种功能。可以询问服务器通常支持哪些方法,或者对某些特殊资源支持哪些方法。
这为客户端应用程序提供了一种手段,使其不用实际访问那些资源就能判定访问各种资源的最优方式。
DELETE
顾名思义,DELETE 方法所做的事情就是请服务器删除请求URL 所指定的资源。
扩展方法
状态码
100~199信息性状态码
100 Continue:HTTP 客户端应用程序有一个实体的主体部分要发送给服务器,但希望在发送之前查看一下服务器是否会接受这个实体。
1.客户端与100 Continue
如果客户端在向服务器发送一个实体,并且愿意在发送实体之前等待100 Continue响应,那么,客户端就要发送一个携带了值为100 Continue 的Expect 请求首部(参见附录C)。如果客户端没有发送实体,就不应该发送100 Continue Expect 首部,因为这样会使服务器误以为客户端要发送一个实体。
从很多方面来看,100 Continue 都是一种优化。客户端应用程序只有在避免向服务器发送一个服务器无法处理或使用的大实体时,才应该使用100 Continue。
2.服务器与100 Continue
如果服务器收到了一条带有值为100 Continue 的Expect 首部的请求,它会用100Continue 响应或一条错误码来进行响应。
3.代理与100 Continue
如果代理从客户端收到了一条带有100 Continue 期望的请求,它需要做几件事情。如果代理知道下一跳服务器(在第6 章中讨论)是HTTP/1.1 兼容的,或者并不知道下一跳服务器与哪个版本兼容,它都应该将Expect 首部放在请求中向下转发。
200~299成功状态码
300~399重定向状态码
重定向状态码要么告知客户端使用替代位置来访问他们所感兴趣的资源,要么就提供一个替代的响应而不是资源的内容。如果资源已被移动,可发送一个重定向状态码和一个可选的Location 首部来告知客户端资源已被移走,以及现在可以在哪里找到它。这样,浏览器就可以在不打扰使用者的情况下,透明地转入新的位置了。
可以通过某些重定向状态码对资源的应用程序本地副本与源端服务器上的资源进行验证。
以下是重定向状态码
400~499客户端错误状态码
500~599服务器错误状态码
首部
可以将首部分为五个主要的类型。
- 通用首部
这些是客户端和服务器都可以使用的通用首部。可以在客户端、服务器和其他应用程序之间提供一些非常有用的通用功能。比如,Date 首部就是一个通用首部,每一端都可以用它来说明构建报文的时间和日期
- 请求首部
从名字中就可以看出,请求首部是请求报文特有的。它们为服务器提供了一些额外信息,比如客户端希望接收什么类型的数据。Accept 首部就用来告知服务器客户端会接受与其请求相符的任意媒体类型。
- 响应首部
- 实体首部
比如,可以用实体首部来说明实体主体部分的数据类型。
- 扩展首部
通用首部
通用缓存首部
HTTP/1.0 引入了第一个允许HTTP 应用程序缓存对象本地副本的首部,这样就不需要总是直接从源端服务器获取了。最新的HTTP 版本有非常丰富的缓存参数集。第7 章深入讨论了缓存。
请求首部
1.Accept首部
2. 条件请求首部
3. 安全请求首部
4. 代理请求首部
响应首部
1. 协商首部
2. 安全响应首部
实体首部
1. 内容首部
2. 实体缓存首部