本文摘自书籍《HTTP 权威指南》
HTTP 报文
HTTP报文是由一行一行的简单字符串组成的,是在HTTP应用程序之间发送的数据块,这些数据块以一些文本形式的元信息(meta-information)开头,这些信息描述了报文的内容及含义,后面跟着可选的数据部分。
报文流
报文在客户端、服务器核代理之间流动。术语:流入、流出、上游、下游。将客户端报文流向服务器的方向称为流入;相反为流出。而报文起始处称为上游,反之为下游。
报文的组成
请求报文:
GET /YuanLicc HTTP/1.1
Host: github.com
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
...
响应报文:
HTTP/1.1 200 OK
Date: Sun, 27 May 2018 07:58:46 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Server: GitHub.com
Status: 200 OK
Cache-Control: no-cache
Vary: X-Requested-With
...
HTTP报文分为以下三个部分:
- 起始行
- 首部字段
- 主体
起始行与首部是由行
分隔的ASCII文本(每行都以一个由两个字符组成的行终止序列作为结束,其中包括一个回车符(ASCII 码 13)和一个换行符(ASCII 码 10))。这个行终止序列可以写做 CRLF。需要指出的是,尽管 HTTP 规范中说明应该用 CRLF 来表示行终止,但稳健的应用程序也应该接受单个换行符作为行的终止。有些老的,或不完整的 HTTP 应用程序并不总是既发送回车符,又发送换行符。)。Note:即使是没有任何首部或者主体,都应该含有CRLF。
起始行
报文的第一行就是起始行,起始行根据报文为请求报文和响应报文分为请求行、响应行。
请求行
请求行由三部分组成:
[method] [request-URL] [version]
响应行
响应行由三部分组成:
[version] [status] [reason-phrase]
method
方法,客户端希望服务器对资源执行的动作。
方法 | 描述 | 是否包含主体 |
---|---|---|
GET | 从服务器获取一份文档 | 否 |
HEAD | 只从服务器获取文档的首部 | 否 |
POST | 向服务器发送需要处理的数据 | 是 |
PUT | 将请求的主体部分存储在服务器上 | 是 |
TRACE | 对可能经过代理服务器传送到服务器上去的报文进行追踪 | 否 |
OPTIONS | 决定可以在服务器上执行哪些方法 | 否 |
DELETE | 从服务器上删除一份文档 | 否 |
- GET
是最常用的方法。通常用于请求服务器发送某个资源。
HEAD
与 GET 方法的行为很类似,但服务器在响应中只返回首部。不会返回实体的主体部分。这就允许客户端在未获取实际资源的情况下,对资源的首部进行检查。
- 在不获取资源的情况下了解资源的情况(比如,判断其类型);
- 通过查看响应中的状态码,看看某个对象是否存在;
- 通过查看首部,测试资源是否被修改了。
PUT
与 GET 从服务器读取文档相反,PUT 方法会向服务器写入文档。
POST
POST 方法起初是用来向服务器输入数据的。实际上,通常会用它来支持 HTML 的表单。表单中填好的数据通常会被送给服务器,然后由服务器将其发送到它要去的地方(比如,送到一个服务器网关程序中,然后由这个程序对其进行处理)。
TRACE
客户端发起一个请求时,这个请求可能要穿过防火墙、代理、网关或其他一些应用程序。每个中间节点都可能会修改原始的 HTTP 请求。TRACE 方法允许客户端在最终将请求发送给服务器时,看看它变成了什么样子。 TRACE 请求会在目的服务器端发起一个“环回”诊断。行程最后一站的服务器会弹回一条 TRACE 响应,并在响应主体中携带它收到的原始请求报文。这样客户端就可以查看在所有中间 HTTP 应用程序组成的请求 / 响应链上,原始报文是否,以及如何被毁坏或修改过。
OPTIONS
方法请求 Web 服务器告知其支持的各种功能。可以询问服务器通常支持哪些方法,或者对某些特殊资源支持哪些方法。(有些服务器可能只支持对一些特殊类型的对象使用特定的操作)
DELETE
请求服务器删除指定URL的资源。
Note :上诉方法不是所有服务器都实现了,由于HTTP的扩展性,可能除了上诉几种方法以外,还实现了一些独有的请求方法。这些附加的方法称为扩展方法。
request-URL
请求URL,标识着资源位置,是请求的目标资源。
version
版本,为HTTP应用程序提供了一种将自己遵循的协议版本告知对方的方式。其格式如下:
HTTP/[major].[minor]
其中major表示主版本号;minor表示次版本号。它们都是整数。
status
状态码,它是一个三位的数字,描述了请求过程中所发生的情况。每个状态码的第一位数字都用于描述状态的一般类别(成功、失败等)。
整体范围 | 已定义范围 | 分类 |
---|---|---|
100~199 | 100~101 | 信息提示 |
200~299 | 200~206 | 成功 |
300~399 | 300~305 | 重定向 |
400~499 | 400~415 | 客户端错误 |
500~599 | 500~505 | 服务器错误 |
常见的状态码:
状态码 | 原因短语 | 含义 |
---|---|---|
200 | OK | 成功,请求的所有数据都在响应主体中 |
401 | Unauthorized | 未授权,需要输入用户名和密码 |
404 | Not Found | 未找到,服务器无法找到所请求URL对应的资源 |
reason-phrase
原因短语,前面状态码的可读版本,可以称为状态码的一种语言解释,易于让人们理解。
首部
起始行后可以有零或多个首部字段。每个首部字段都包含一个名字和一个值,为了便于解析,两者之间用冒汗来分隔。首部以一个空行结束,标示着首部列表结束以及主体部分的开始。常见首部:
首部实例 | 描述 |
---|---|
Host: github.com | 接收请求的主机地址及端口(默认为80) |
Date: Sun, 27 May 2018 07:58:46 GMT | 服务器产生响应时间 |
Content-length:15040 | 实体主体部分包含15040字节的数据 |
Content-type:image/gif | 实体主体部分是一张gif图片 |
Accept: image/gif, image/jpeg, text/html | 客户端可接收gif、jpeg、html |
首部延续行
将长的首部分为多行可提高可读性,多出来的每行前面至少需要一个空格或制表符(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
。
通用信息性首部
首部 | 描述 |
---|---|
Connection | 允许客户端和服务器指定与请求/响应连接有关的选项 |
Date | 提供日期和时间标志,说明报文是什么时间创建的 |
MIME-Version | 给出了发送端使用的MIME版本 |
Trailer | 如果报文采用了分块传输编码(chunked transfer encoding)方式,就可以用这个首部列出位于报文拖挂(trailer)部分的首部集合 |
Transfer-Encoding | 告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式 |
Update | 给出了发送端可能想要“升级”使用的新版本或协议 |
Via | 显示了报文经过的中间节点(代理、网关) |
Cache-Control | 用于随报文传送缓存指示 |
Pragma | 另一种随报文传送指示的方式,但并不专用于缓存 |
请求信息性首部
首部 | 描述 |
---|---|
Client-IP4 | 提供了运行客户端的机器的IP地址 |
From | 提供了客户端用户的E-mail地址 |
Host | 给出了接收请求的服务器的主机名和端口号 |
Referer | 提供了包含当前请求URI的文档的URL |
UA-Color | 提供了与客户端显示器的显示颜色有关的信息 |
UA-CPU | 给出了客户端CPU的类型或制造商 |
UA-Disp | 提供了与客户端显示器(屏幕)能力有关的信息 |
UA-OS | 给出了运行在客户端机器上的操作系统名称及版本 |
UA-Pixels | 提供了客户端显示器的像素信息 |
User-Agent | 将发起请求的应用程序名称告知服务器 |
Authorization | 包含了客户端提供给服务器,以便对其自身进行认证的数据 |
Cookie | 客户端用它向服务器传送一个令牌——它并不是真正的安全首部,但确实隐含了安全功能 |
请求喜好与能力首部(ACCEPT首部)
Accept 首部为客户端提供了一种将其喜好和能力告知服务器的方式,包括它们想要什么,可以使用什么,以及最重要的,它们不想要什么。这样,服务器就可以根据这些额外信息,对要发送的内容做出更明智的决定。
首部 | 描述 |
---|---|
Accept | 告诉服务器能够发送哪些媒体类型 |
Accept-Charset | 告诉服务器能够发送哪些字符集 |
Accept-Encoding | 告诉服务器能够发送哪些编码方式 |
Accept-Language | 告诉服务器能够发送哪些语言 |
TE | 告诉服务器可以使用哪些扩展传输编码 |
请求条件首部
有时客户端希望为请求加上某些限制。比如,如果客户端已经有了一份文档副本,就希望只在服务器上的文档与客户端拥有的副本有所区别时,才请求服务器传输文档。通过条件请求首部,客户端就可以为请求加上这种限制,要求服务器在对请求进行响应之前,确保某个条件为真。
首部 | 描述 |
---|---|
Expect | 允许客户端列出某请求所要求的服务器行为 |
If-Match | 如果实体标记与文档当前的实体标记相匹配,就获取这份文档 |
If-Modified-Since | 除非在某个指定的日期之后资源被修改过,否则就限制这个请求 |
If-None-Match | 如果提供的实体标记与当前文档的实体标记不相符,就获取文档 |
If-Range | 允许对文档的某个范围进行条件请求 |
If-Unmodified-Since | 除非在某个指定日期之后资源没有被修改过,否则就限制这个请求 |
Range | 如果服务器支持范围请求,就请求资源的指定范围 |
请求代理首部
首部 | 描述 |
---|---|
Max-Forward | 在通往源端服务器的路径上,将请求转发给其他代理或网关的最大次数——与TRACE方法一同使用 |
Proxy-Authorization | 与Authorization 首部相同,但这个首部是在与代理进行认证时使用的 |
Proxy-Connection | 与Connection 首部相同,但这个首部是在与代理建立连接时使用的 |
响应信息性首部
首部 | 描述 |
---|---|
Age | (从最初创建开始)响应持续时间 |
Public | 服务器为其资源支持的请求方法列表 |
Retry-After | 如果资源不可用的话,在此日期或时间重试 |
Server | 服务器应用程序软件的名称和版本 |
Title | 对HTML文档来说,就是HTML文档的源端给出的标题 |
Warning | 比原因短语中更详细一些的警告报文 |
响应协商首部
如果资源有多种表示方法——比如,如果服务器上有某文档的法语和德语译稿,HTTP/1.1 可以为服务器和客户端提供对资源进行协商的能力。
首部 | 描述 |
---|---|
Accept-Ranges | 对此资源来说,服务器可接受的范围类型 |
Vary | 服务器查看的其他首部的列表,可能会使响应发生变化;也就是说,这是一个首部列表,服务器会根据这些首部的内容挑选出最适合的资源版本发送给客户端 |
响应安全首部
首部 | 描述 |
---|---|
Proxy-Authenticate | 来自代理的对客户端的质询列表 |
Set-Cookie | 不是真正的安全首部,但隐含有安全功能;可以在客户端设置一个令牌,以便服务器对客户端进行标识 |
Set-Cookie2 | 与Set-Cookie 类似,RFC 2965 Cookie定义 |
WWW-Authenticate | 来自服务器的对客户端的质询列表 |
实体信息性首部
首部 | 描述 |
---|---|
Allow | 列出了可以对此实体执行的请求方法 |
Location | 告知客户端实体实际上位于何处;用于将接收端定向到资源的(可能是新的)位置(URL)上去 |
实体内容首部
首部 | 描述 |
---|---|
Content-Base | 解析主体中的相对URL时使用的基础URL |
Content-Encoding | 对主体执行的任意编码方式 |
Content-Language | 理解主体时最适宜使用的自然语言 |
Content-Length | 主体的长度或尺寸 |
Content-Location | 资源实际所处的位置 |
Content-MD5 | 主体的MD5校验和 |
Content-Range | 在整个资源中此实体表示的字节范围 |
Content-Type | 这个主体的对象类型 |
主体
首部空行之后为可选的报文主体,其中包含了所有类型的数据。请求主体中包含了要发送给服务器的数据;响应主体中装载了要返回给客户端的数据。起始行和首部都是文本形式且都是结构化的,而主体则不同,主体可以包含任意的二进制数据(图片、视频等),主体也可以包含文本。