• 报文是如何流动的;
• HTTP 报文的三个组成部分(起始行、首部和实体的主体部分);
• 请求和响应报文之间的区别;
• 请求报文支持的各种功能(方法);
• 和响应报文一起返回的各种状态码;
• 各种各样的 HTTP 首部都是用来做什么的。
3.1 报文流
3.1.1 报文流入源端服务器
HTTP 使用术语流入(inbound)和流出(outbound)来描述事务处理(transaction)的方向。报文流入源端服务器,工作完成之后,会流回用户的Agent 代理中
对请求报文来说,代理1 位于代理3 的上游,但对响应报文来说,它就位于代理3 的下游1
3.2 报文的组成部分
由三个部分组成:对报文进行描述的起始行(start line)、包含属性的首部(header)块,以及可选的、包含数据的主体(body)部分。
3.2.1 报文的语法
所有的HTTP 报文都可以分为两类: 请求报文(request message) 和响应报文(response message)。请求报文会向Web 服务器请求一个动作。响应报文会将请求的结果返回给客户端。请求和响应报文的基本报文结构相同。
• 方法(method)
客户端希望服务器对资源执行的动作。是一个单独的词,比如GET、HEAD 或POST。
• 请求URL(request-URL)
命名了所请求资源,或者URL 路径组件的完整URL。如果直接与服务器进行对话,只要URL 的路径组件是资源的绝对路径,通常就不会有什么问题——服务器可以假定自己是URL 的主机/ 端口。第2 章详细地介绍了URL 的语法。
• 版本(version)
报文所使用的HTTP 版本,其格式看起来是这样的:HTTP/<major>.<minor>其中主要版本号(major)和次要版本号(minor)都是整数。本章稍后会详细说明HTTP 的版本问题。
• 状态码(status-code)
这三位数字描述了请求过程中所发生的情况。每个状态码的第一位数字都用于描述状态的一般类别(“成功”、“出错”等)。本章稍后提供了HTTP 规范定义的状态码及其含义的完整列表。
• 原因短语(reason-phrase)
数字状态码的可读版本,包含行终止序列之前的所有文本。本章稍后提供了HTTP 规范定义的所有状态码的原因短语示例。原因短语只对人类有意义,因此,比如说,尽管响应行HTTP/1.0 200 NOT OK 和 HTTP/1.0 200 OK 中原因短语的含义不同,但同样都会被当作成功指示处理。
• 首部(header)
可以有零个或多个首部,每个首部都包含一个名字,后面跟着一个冒号(:),然后是一个可选的空格,接着是一个值,最后是一个CRLF。首部是由一个空行(CRLF)结束的,表示了首部列表的结束和实体主体部分的开始。有些HTTP 版本,比如HTTP/1.1,要求有效的请求或响应报文中必须包含特定的首部。本章稍后会探讨各种HTTP 首部。
• 实体的主体部分(entity-body)
实体的主体部分包含一个由任意数据组成的数据块。并不是所有的报文都包含实体的主体部分,有时,报文只是以一个CRLF 结束
3.2.2 起始行
所有的HTTP 报文都以一个起始行作为开始。请求报文的起始行说明了要做些什么。
响应报文的起始行说明发生了什么。
1. 请求行
包含了一个方法和一个请求URL,还包含HTTP 的版本,用来告知服务器,客户端使用的是哪种HTTP。
2. 响应行
包含了响应报文使用的HTTP 版本、数字状态码,以及描述操作状态的文本形式的原因短语。所有这些字段都由空格符进行分隔
3. 方法
4. 状态码
5. 原因短语
原因短语是响应起始行中的最后一个组件。它为状态码提供了文本形式的解释。比如,在行HTTP/1.0 200 OK 中,OK 就是原因短语。
6. 版本号
版本号会以HTTP/x.y 的形式出现在请求和响应报文的起始行中
3.2.3 首部
首部分类
HTTP 规范定义了几种首部字段。应用程序也可以随意发明自己所用的首部。HTTP首部可以分为以下几类。
• 通用首部
既可以出现在请求报文中,也可以出现在响应报文中。
• 请求首部
提供更多有关请求的信息。
• 响应首部
提供更多有关响应的信息。
• 实体首部
描述主体的长度和内容,或者资源自身。
• 扩展首部
规范中没有定义的新首部。
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。
3.2.4 实体的主体部分
HTTP 报文的第三部分是可选的实体主体部分。实体的主体是HTTP 报文的负荷。就是HTTP 要传输的内容。
HTTP 报文可以承载很多类型的数字数据:图片、视频、HTML 文档、软件应用程序、信用卡事务、电子邮件等。
3.3 方法
3.3.1 安全方法
HTTP 定义了一组被称为安全方法的方法。GET 方法和HEAD 方法都被认为是安全的,这就意味着使用GET 或HEAD 方法的HTTP 请求都不会产生什么动作。
3.3.2 GET
3.3.3 HEAD
3.3.4 PUT
3.3.5 POST
POST 方法起初是用来向服务器输入数据的3。实际上,通常会用它来支持HTML的表单。表单中填好的数据通常会被送给服务器,然后由服务器将其发送到它要去的地方(比如,送到一个服务器网关程序中,然后由这个程序对其进行处理)
3.3.6 TRACE
客户端发起一个请求时,这个请求可能要穿过防火墙、代理、网关或其他一些应用程序。每个中间节点都可能会修改原始的HTTP 请求。TRACE 方法允许客户端在最终将请求发送给服务器时,看看它变成了什么样子。
TRACE 方法主要用于诊断;也就是说,用于验证请求是否如愿穿过了请求/ 响应链。它也是一种很好的工具,可以用来查看代理和其他应用程序对用户请求所产生效果。
3.3.7 OPTIONS
OPTIONS 方法请求Web 服务器告知其支持的各种功能。
3.3.8 DELETE
DELETE 方法所做的事情就是请服务器删除请求URL 所指定的资源。
3.3.9 扩展方法
3.4 状态码
3.4.1 100~199——信息性状态码
1. 客户端与100 Continue
客户端在向服务器发送一个实体,并且愿意在发送实体之前等待100 Continue响应,那么,客户端就要发送一个携带了值为100 Continue 的Expect 请求首部
2. 服务器与100 Continue
服务器收到了一条带有值为100 Continue 的Expect 首部的请求,它会用100Continue 响应或一条错误码来进行响应
3. 代理与100 Continue
代理从客户端收到了一条带有100 Continue 期望的请求,它需要做几件事情。如果代理知道下一跳服务器(在第6 章中讨论)是HTTP/1.1 兼容的,或者并不知道下一跳服务器与哪个版本兼容,它都应该将Expect 首部放在请求中向下转发。如果它知道下一跳服务器只能与HTTP/1.1 之前的版本兼容,就应该以417Expectation Failed 错误进行响应
3.4.2 200~299——成功状态码
3.4.3 300~399——重定向状态码
重定向状态码要么告知客户端使用替代位置来访问他们所感兴趣的资源,要么就提供一个替代的响应而不是资源的内容。如果资源已被移动,可发送一个重定向状态码和一个可选的Location 首部来告知客户端资源已被移走,以及现在可以在哪里找到它。这样,浏览器就可以在不打扰使用者的情况下,透明地转入新的位置了。
302、303 和307 状态码之间存在一些交叉。这些状态码的用法有着细微的差别,大部分差别都源于HTTP/1.0 和HTTP/1.1 应用程序对这些状态码处理方式的不同。
3.4.4 400~499——客户端错误状态码
3.4.5 500~599——服务器错误状态码
有时客户端发送了一条有效请求,服务器自身却出错了。这可能是客户端碰上了服务器的缺陷,或者服务器上的子元素,比如某个网关资源,出了错。
3.5 首部
在请求和响应报文中都可以用首部来提供信息,有些首部是某种报文专用的,有些首部则更通用一些。可以将首部分为五个主要的类型。
• 通用首部
这些是客户端和服务器都可以使用的通用首部。可以在客户端、服务器和其他应用程序之间提供一些非常有用的通用功能。比如,Date 首部就是一个通用首部,每一端都可以用它来说明构建报文的时间和日期:Date: Tue, 3 Oct 1974 02:16:00 GMT
• 请求首部
从名字中就可以看出,请求首部是请求报文特有的。它们为服务器提供了一些额外信息,比如客户端希望接收什么类型的数据。例如,下面的Accept 首部就用来告知服务器客户端会接受与其请求相符的任意媒体类型:
Accept: */*
• 响应首部
响应报文有自己的首部集,以便为客户端提供信息(比如,客户端在与哪种类型的服务器进行交互)。例如,下列Server 首部就用来告知客户端它在与一个版本1.0 的Tiki-Hut 服务器进行交互:
Server: Tiki-Hut/1.0
• 实体首部
实体首部指的是用于应对实体主体部分的首部。比如,可以用实体首部来说明实体主体部分的数据类型。例如,可以通过下列Content-Type 首部告知应用程序,数据是以iso-latin-1 字符集表示的HTML 文档:
Content-Type: text/html; charset=iso-latin-1
• 扩展首部
扩展首部是非标准的首部,由应用程序开发者创建,但还未添加到已批准的HTTP 规范中去。即使不知道这些扩展首部的含义,HTTP 程序也要接受它们并
对其进行转发。
3.5.1 通用首部
通用缓存首部
3.5.2 请求首部
1. Accept首部
Accept 首部为客户端提供了一种将其喜好和能力告知服务器的方式,包括它们想要什么,可以使用什么,以及最重要的,它们不想要什么。这样,服务器就可以根据这些额外信息,对要发送的内容做出更明智的决定。Accept 首部会使连接的两端都受益。客户端会得到它们想要的内容,服务器则不会浪费其时间和带宽来发送客户端无法使用的东西
2. 条件请求首部
4. 代理请求首部