- HTTP 报文是简单的格式化数据块。它们由三个部分组成:
- 对报文进行描述的起始行(start line);
- 包含属性的首部(header)块;
- 可选的、包含数据的主体(body)部分。
- 起始行和首部就是由行分隔的 ASCII 文本。每行都以一个由两个字符组成的“行终止序列”作为结束,其中包括一个回车符(ASCII 码 13)和一个换行符(ASCII 码 10)。 这个行终止序列可以写做 CRLF。
- 尽管 HTTP 规范中说明应该用 CRLF 来表示行终止,但稳健的应用程序也应该接受单个换行符作为行的终止。有些老的,或不完整的 HTTP 应用程序并不总是既发送回车符,又发送换行符。
- 主体是可选的数据块,与起始行和首部不同的是,主体中可以包含文本或二进制数据,也可以为空。
1. 报文的语法
- 请求报文的格式:从客户端发往服务器的报文。
<method> <request-URL> <version> //起始行
<headers> //首部
//空一行
<entity-body> //主体- 响应报文的格式:从服务器发往客户端的报文。
<version> <status-code> <reason-phrase> //起始行(注意,只有起始行的语法有所不同)
<headers> //首部
//空一行
<entity-body> //主体- 各部分简述:
- 方法(method):客户端希望服务器对资源执行的动作。是一个单独的词,比如 GET、HEAD 或 POST。
- 请求URL(request-URL):命名了所请求资源,或者 URL 路径组件的完整 URL。如果直接与服务器进行对话,只要 URL 的路径组件是资源的绝对路径,通常就不会有什么问题——服务器可以假定自己是 URL 的主机 / 端口。
- 版本(version):报文所使用的 HTTP 版本,其格式看起来是这样的
HTTP/<major>.<minor>,其中主要版本号(major)和次要版本号(minor)都是整数。 - 状态码(status-code):这三位数字描述了请求过程中所发生的情况。每个状态码的第一位数字都用于描述状态的一般类别(“成功”、“出错”等)。
- 原因短语(reason-phrase):数字状态码的可读版本,包含行终止序列之前的所有文本。原因短语只对人类有意义,因此,比如说,尽管响应行 HTTP/1.0 200 NOT OK 和 HTTP/1.0 200 OK 中原因短语的含义不同,但同样都会被当作成功指示处理。
- 首部(header):可以有零个或多个首部,每个首部都包含一个名字,后面跟着一个冒号(:),然后是一个可选的空格,接着是一个值,最后是一个 CRLF。首部是由一个空行(CRLF)结束的,表示了首部列表的结束和实体主体部分的开始。有些 HTTP 版本,比如 HTTP/1.1,要求有效的请求或响应报文中必须包含特定的首部。
- 实体的主体部分(entity-body):实体的主体部分包含一个由任意数据组成的数据块。并不是所有的报文都包含实体的主体部分,有时,报文只是以一个 CRLF 结束。
- 注意,一组 HTTP 首部总是应该以一个空行(仅有 CRLF)结束,甚至即使没有首部和实体的主体部分也应如此。但由于历史原因,很多客户端和服务器都在没有实体的主体部分时,(错误地)省略了最后的 CRLF。为了与这些流行但不符合规则的实现进行互通,客户端和服务器都应该接受那些没有最后那个 CRLF 的报文。
2. 起始行
- 所有的 HTTP 报文都以一个起始行作为开始。请求报文的起始行说明了要做些什么。响应报文的起始行说明发生了什么。
1. 请求行
- 请求报文请求服务器对资源进行一些操作。请求报文的起始行,或称为请求行。
- 包含了一个方法、一个请求 URL和一个 HTTP 的版本。
- 方法:描述了服务器应该执行的操作。
- 请求 URL:描述了要对哪个资源执行这个方法。
- HTTP 版本:用来告知服务器,客户端使用的是哪种 HTTP。
- 所有这些字段都由空格符分隔。
- 常用7种 HTTP 方法:
| 方法 | 描述 | 是否包含主体 |
|---|---|---|
| GET | 从服务器获取一份文档 | 否 |
| HEAD | 只从服务器获取文档的首部 | 否 |
| POST | 向服务器发送需要处理的数据 | 是 |
| PUT | 将请求的主体部分存储在服务器上 | 是 |
| TRACE | 对可能经过代理服务器传送到服务器上去的报文进行追踪 | 否 |
| OPTIONS | 决定可以在服务器上执行哪些方法 | 否 |
| DELETE | 从服务器上删除一份文档 | 否 |
并不是所有服务器都实现了表中列出的所有 7 种方法。而且,由于 HTTP 设计得易于扩展,所以除了这些方法之外,其他服务器可能还会实现一些自己的请求方法。这些附加的方法是对 HTTP 规范的扩展,因此被称为扩展方法。
2. 响应行
- 响应报文承载了状态信息和操作产生的所有结果数据,将其返回给客户端。响应报文的起始行,或称为响应行。
- 包含了响应报文使用的 HTTP 版本、数字状态码,以及描述操作状态的文本形式的原因短语。
- 所有这些字段都由空格符进行分隔。
- 在 HTTP/1.0 之前,并不要求在响应中包含响应行。
- 状态码分类:
| 整体范围 | 已定义范围 | 分类 |
|---|---|---|
| 100 ~ 199 | 100 ~ 101 | 信息提示 |
| 200 ~ 299 | 200 ~ 206 | 成功 |
| 300 ~ 399 | 300 ~ 305 | 重定向 |
| 400 ~ 499 | 400 ~ 415 | 客户端错误 |
| 500 ~ 599 | 500 ~ 505 | 服务器错误 |
* 当前的 HTTP 版本只为每类状态定义了几个代码。随着协议的发展,HTTP 规范中会正式地定义更多的状态码。如果收到了不认识的状态码,可能是有人将其作为当前协议的扩展定义的。可以根据其所处范围,将它作为那个类别中一个普通的成员来处理。
3. HTTP 版本号
- 版本号会以 HTTP/x.y 的形式出现在请求和响应报文的起始行中。为 HTTP 应用程序提供了一种将自己所遵循的协议版本告知对方的方式。
- 在与使用 HTTP 1.1 的应用程序进行通信的 HTTP 1.2 应用程序应该知道,它不能使用任何新的 1.2 特性,因为使用老版本协议的应用程序很可能无法实现这些特性。
- 版本号说明了应用程序支持的最高 HTTP 版本。但 HTTP/1.0 应用程序在解释包含 HTTP/1.1 的响应时,会认为这个响应是个 1.1 响应,而实际上这只是响应应用程序所使用的协议等级,在这些情况下,版本号会在应用程序之间造成误解。http://httpd.apache.org/docs-2.0/misc/known_client_problems.html 上有更多在 Apache 与客户端之间出现 此问题的案例。
- 注意,版本号不会被当作小数来处理。版本中的每个数字(比如 HTTP/1.0 中的 1 和 0)都会被当作一个单独的数字来处理。因此,在比较 HTTP 版本时,每个数字都必须单独进行比较,以便确定哪个版本更高。比如,HTTP/2.22 就比 HTTP/2.3 的版本要高,因为 22 比 3 大。
3. 首部
- 跟在起始行后面的就是零个、一个或多个 HTTP 首部字段。
- HTTP 首部字段向请求和响应报文中添加了一些附加信息。本质上来说,它们只是一些名 / 值对的列表。
1. 首部分类
- HTTP 规范定义了几种首部字段。应用程序也可以随意发明自己所用的首部。HTTP首部可以分为以下几类:
- 通用首部:既可以出现在请求报文中,也可以出现在响应报文中。
- 请求首部:提供更多有关请求的信息。
- 响应首部:提供更多有关响应的信息。
- 实体首部:描述主体的长度和内容,或者资源自身。
- 扩展首部:规范中没有定义的新首部。
- 首部语法:名字后面跟着冒号( :),然后跟上可选的空格,再跟上字段值,最后是一个 CRLF。
- 常见首部实例:
| 首部实例 | 描述 |
|---|---|
| Date:Tue,3Oct 1997 02:16:03 GMT | 服务器产生响应的日期 |
| Content-length:15040 | 实体的主体部分包含了 15040 字节的数据 |
| Content-type:image/gif | 实体的主体部分是一个 GIF 图片 |
| Accept: image/gif, image/jpeg, text/html | 客户端可以接收GIF图片和JPEG图片以及HTML |
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。4. 主体
- HTTP 报文的第三部分是可选的实体主体部分。实体的主体是 HTTP 报文的负荷,就是 HTTP 要传输的内容。
- HTTP 报文可以承载很多类型的数字数据:图片、视频、HTML 文档、软件应用程序、信用卡事务、电子邮件等。
5. HTTP/0.9的报文
- HTTP 版本 0.9 是 HTTP 协议的早期版本。是当今 HTTP 所拥有的请求及响应报文的鼻祖,但其协议要简单得多。
- HTTP/0.9 报文也由请求和响应组成,但请求中只包含方法和请求 URL,响应中只包含实体。
- 它没有版本信息(它是第一个,而且是当时唯一的版本),没有状态码或 原因短语,也没有首部。
- 但这种简单协议无法提供更多的灵活性,也无法实现大部分 HTTP 特性和应用。这里对其进行简要的描述,是因为仍然有一些客户端、服务器和其他应用程序在使用这个协议,应用程序的编写者应该清楚它的局限性。
版权声明:本文为gogzf原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。