3.5 首部
首部和方法配合工作,共同决定了客户端和服务器能做什么事情。本节快速介绍了使用标准 HTTP 首部及一些没有在 HTTP/1.1 规范(RFC 2616)中明确定义的首部的目的。附录 C 对所有这些首部进行了更详细的总结。
在请求和响应报文中都可以用首部来提供信息,有些首部是某种报文专用的,有些首部则更通用一些。可以将首部分为五个主要的类型。
- 通用首部
这些是客户端和服务器都可以使用的通用首部。可以在客户端、服务器和其他应用程序之间提供一些非常有用的通用功能。比如,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-11 列出了通用的信息性首部。
表3-11 通用的信息性首部
首 部 | 描 述 |
---|---|
Connection | 允许客户端和服务器指定与请求/响应连接有关的选项 |
Date 1 | 提供日期和时间标志,说明报文是什么时间创建的 |
MIME-Version | 给出了发送端使用的MIME版本 |
Trailer | 如果报文采用了分块传输编码(chunked transfer encoding)方式,就可以用这个首部列出位于报文拖挂(trailer)部分的首部集合2 |
Transfer-Encoding | 告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式 |
Update | 给出了发送端可能想要“升级”使用的新版本或协议 |
Via | 显示了报文经过的中间节点(代理、网关) |
1 Date
中列出了 Date
首部可接受的日期格式。
2 15.6.3 节详细探讨了分块传输编码。
通用缓存首部
HTTP/1.0 引入了第一个允许 HTTP 应用程序缓存对象本地副本的首部,这样就不需要总是直接从源端服务器获取了。最新的 HTTP 版本有非常丰富的缓存参数集。第 7 章深入讨论了缓存。表 3-12 列出了基本的缓存首部。
表3-12 通用缓存首部
首 部 | 描 述 |
---|---|
Cache-Control | 用于随报文传送缓存指示 |
Pragma 3 | 另一种随报文传送指示的方式,但并不专用于缓存 |
3 从技术角度来看,Pragma
是一种请求首部。从未被指定用于响应首部。由于经常被错误地用于响应首部,很多客户端和代理都会将 Pragma
解释为响应首部,但其确切语义并未得到很好地定义。任何情况下 Cache-Control
的使用都优于 Pragma
。
3.5.2 请求首部
请求首部是只在请求报文中有意义的首部。用于说明是谁或什么在发送请求、请求源自何处,或者客户端的喜好及能力。服务器可以根据请求首部给出的客户端信息,试着为客户端提供更好的响应。表 3-13 列出了请求的信息性首部。
表3-13 请求的信息性首部
首 部 | 描 述 |
---|---|
Client-IP 4 | 提供了运行客户端的机器的IP地址 |
From | 提供了客户端用户的E-mail地址5 |
Host | 给出了接收请求的服务器的主机名和端口号 |
Referer | 提供了包含当前请求URI的文档的URL |
UA-Color | 提供了与客户端显示器的显示颜色有关的信息 |
UA-CPU 6 | 给出了客户端CPU的类型或制造商 |
UA-Disp | 提供了与客户端显示器(屏幕)能力有关的信息 |
UA-OS | 给出了运行在客户端机器上的操作系统名称及版本 |
UA-Pixels | 提供了客户端显示器的像素信息 |
User-Agent | 将发起请求的应用程序名称告知服务器 |
4 RFC 2616 没有定义 Client-IP
和 UA-*
首部,但很多 HTTP 客户端应用程序都实现了这两个首部。
5 使用 RFC 822 E-mail 地址格式。
6 尽管有些客户端实现了 UA-*
首部,但我们认为 UA-*
首部是有副作用的。不应该将内容,尤其是HTML,局限于特定的客户端配置。
Accept
首部
Accept
首部为客户端提供了一种将其喜好和能力告知服务器的方式,包括它们想要什么,可以使用什么,以及最重要的,它们不想要什么。这样,服务器就可以根据这些额外信息,对要发送的内容做出更明智的决定。Accept
首部会使连接的两端都受益。客户端会得到它们想要的内容,服务器则不会浪费其时间和带宽来发送客户端无法使用的东西。表 3-14 列出了各种 Accept
首部。
表3-14 Accept首部
首 部 描 述 Accept
告诉服务器能够发送哪些媒体类型 Accept-Charset
告诉服务器能够发送哪些字符集 Accept-Encoding
告诉服务器能够发送哪些编码方式 Accept-Language
告诉服务器能够发送哪些语言 TE
7 告诉服务器可以使用哪些扩展传输编码
7 更多有关 TE
首部的内容请参见 15.6.2 节。
- 条件请求首部
有时客户端希望为请求加上某些限制。比如,如果客户端已经有了一份文档副本,就希望只在服务器上的文档与客户端拥有的副本有所区别时,才请求服务器传输文档。通过条件请求首部,客户端就可以为请求加上这种限制,要求服务器在对请求进行响应之前,确保某个条件为真。表 3-15 列出了各种条件请求首部。
表3-15 条件请求首部
首 部 描 述 Expect
允许客户端列出某请求所要求的服务器行为 If-Match
如果实体标记与文档当前的实体标记相匹配,就获取这份文档8 If-Modified-Since
除非在某个指定的日期之后资源被修改过,否则就限制这个请求 If-None-Match
如果提供的实体标记与当前文档的实体标记不相符,就获取文档 If-Range
允许对文档的某个范围进行条件请求 If-Unmodified-Since
除非在某个指定日期之后资源没有被修改过,否则就限制这个请求 Range
如果服务器支持范围请求,就请求资源的指定范围9
8 更多有关实体标记的内容请参见第 7 章。标记本质上就是某版本资源的标识符。
9 更多有关 Range
首部的内容请参见 15.9 节。
- 安全请求首部
HTTP 本身就支持一种简单的机制,可以对请求进行质询 / 响应认证。这种机制要求客户端在获取特定的资源之前,先对自身进行认证,这样就可以使事务稍微安全一些。我们会在第 14 章讨论这种质询 / 响应机制,同时还会对在 HTTP 之上实现的其他安全机制进行讨论。表 3-16 列出了一些安全请求首部。
表3-16 安全请求首部
首 部 描 述 Authorization
包含了客户端提供给服务器,以便对其自身进行认证的数据 Cookie
客户端用它向服务器传送一个令牌——它并不是真正的安全首部,但确实隐含了安全功能10 Cookie2
用来说明请求端支持的cookie版本,参见11.6.7节
10 RFC 2616 并没有定义 Cookie
首部,在第 11 章详细讨论了该首部。
- 代理请求首部
随着因特网上代理的普遍应用,人们定义了几个首部来协助其更好地工作。第 6 章对这些首部进行了详细的讨论。表 3-17 列出了一些代理请求首部。
表3-17 代理请求首部
首 部 描 述 Max-Forward
在通往源端服务器的路径上,将请求转发给其他代理或网关的最大次数——与TRACE方法一同使用11 Proxy-Authorization
与Authorization
首部相同,但这个首部是在与代理进行认证时使用的 Proxy-Connection
与Connection
首部相同,但这个首部是在与代理建立连接时使用的
11 参见 6.6.2 节。
3.5.3 响应首部
响应报文有自己的响应首部集。响应首部为客户端提供了一些额外信息,比如谁在发送响应、响应者的功能,甚至与响应相关的一些特殊指令。这些首部有助于客户端处理响应,并在将来发起更好的请求。表 3-18 列出了一些响应的信息性首部。
表3-18 响应的信息性首部
首 部 | 描 述 |
---|---|
Age | (从最初创建开始)响应持续时间12 |
Public 13 | 服务器为其资源支持的请求方法列表 |
Retry-After | 如果资源不可用的话,在此日期或时间重试 |
Server | 服务器应用程序软件的名称和版本 |
Title 14 | 对HTML文档来说,就是HTML文档的源端给出的标题 |
Warning | 比原因短语中更详细一些的警告报文 |
12 暗示响应是通过中间节点,很可能是从代理的缓存传送过来的。
13 Public
首部是在 RFC 2068 中定义的,但在最新的 HTTP 定义(RFC 2616)中并没有出现。
14 RFC 2616 并没有定义 Title
首部。请参见原始的 HTTP/1.0 草案定义(http://www.w3.org/Protocols/HTTP/HTTP2.html)。
- 协商首部
如果资源有多种表示方法——比如,如果服务器上有某文档的法语和德语译稿,HTTP/1.1 可以为服务器和客户端提供对资源进行协商的能力。第 17 章详细讨论了协商。这里列出了几个首部,服务器可以用它们来传递与可协商资源有关的信息。表 3-19 列出了协商首部。
表3-19 协商首部
首 部 描 述 Accept-Ranges
对此资源来说,服务器可接受的范围类型 Vary
服务器查看的其他首部的列表,可能会使响应发生变化;也就是说,这是一个首部列表,服务器会根据这些首部的内容挑选出最适合的资源版本发送给客户端
- 安全响应首部
我们已经看到过安全请求首部了,本质上这里说的就是 HTTP 的质询 / 响应认证机制的响应侧。我们会在第 14 章对安全问题进行详细的讨论。现在这里介绍的是一些基本的质询首部。表 3-20 列出了安全响应首部。
表3-20 安全响应首部
首 部 描 述 Proxy-Authenticate
来自代理的对客户端的质询列表 Set-Cookie
不是真正的安全首部,但隐含有安全功能;可以在客户端设置一个令牌,以便服务器对客户端进行标识15 Set-Cookie2
与Set-Cookie
类似,RFC 2965 Cookie定义;参见11.6.7节 WWW-Authenticate
来自服务器的对客户端的质询列表
15 Set-Cookie
和 Set-Cookie2
都是扩展首部,参见第 11 章。
3.5.4 实体首部
有很多首部可以用来描述 HTTP 报文的负荷。由于请求和响应报文中都可能包含实体部分,所以在这两种类型的报文中都可能出现这些首部。
实体首部提供了有关实体及其内容的大量信息,从有关对象类型的信息,到能够对资源使用的各种有效的请求方法。总之,实体首部可以告知报文的接收者它在对什么进行处理。表 3-21 列出了实体的信息性首部。
表3-21 实体的信息性首部
首 部 | 描 述 |
---|---|
Allow | 列出了可以对此实体执行的请求方法 |
Location | 告知客户端实体实际上位于何处;用于将接收端定向到资源的(可能是新的)位置(URL)上去 |
- 内容首部
内容首部提供了与实体内容有关的特定信息,说明了其类型、尺寸以及处理它所需的其他有用信息。比如,Web 浏览器可以通过查看返回的内容类型,得知如何显示对象。表 3-22 列出了各种内容首部。
表3-22 内容首部
首 部 描 述 Content-Base
16 解析主体中的相对URL时使用的基础URL Content-Encoding
对主体执行的任意编码方式 Content-Language
理解主体时最适宜使用的自然语言 Content-Length
主体的长度或尺寸 Content-Location
资源实际所处的位置 Content-MD5
主体的MD5校验和 Content-Range
在整个资源中此实体表示的字节范围 Content-Type
这个主体的对象类型
16 RFC 2616 中没有定义 Content-Base
首部。
- 实体缓存首部
通用的缓存首部说明了如何或什么时候进行缓存。实体的缓存首部提供了与被缓存实体有关的信息——比如,验证已缓存的资源副本是否仍然有效所需的信息,以及更好地估计已缓存资源何时失效所需的线索。
第 7 章深入讨论了 HTTP 请求和响应的缓存。在那里我们会再次看到这些首部。表3-23 列出了一些实体缓存首部。
表3-23 实体缓存首部
首 部 描 述 ETag
与此实体相关的实体标记17 Expires
实体不再有效,要从原始的源端再次获取此实体的日期和时间 Last-Modified
这个实体最后一次被修改的日期和时间
17 实体标记本质上来说就是某个特定资源版本的标识符。