请求首部字段是从客户端往服务器端发送请求报文中所使用的字段,用于补充请求的附加信息、客户端信息、对响应内容相关的优先级等内容。
图:HTTP 请求报文中使用的首部字段
Accept
Accept 首部字段用于告知服务器用户代理能够处理的媒体类型及媒体类型的相对优先级。可使用 type/subtype(类型/子类型) 这种形式,一次指定多种媒体类型。
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
图:HTTP 请求报文中使用的首部字段
下面我们试举几个媒体类型的例子:
- 文本文件
text/html、text/plain、text/css ...
application/xhtml+xml、application/xml ...
- 图片文件
image/jpeg、image/gif、image/png ...
- 视频文件
video/mpeg、video/quicktime ...
- 应用程序使用的二进制文件¬
application/octet-stream、application/zip ...
比如,如果浏览器不支持 PNG 图片的显示,那 Accept 就不指定 image/png,而指定可处理的 image/gif 和 image/jpeg 等图片类型。
若想要给显示的媒体类型增加优先级,则使用 q=
来额外表示权重值,用分号 ;
进行分隔。权重值 q 的范围是 0~1(可精确到小数点后 3 位),且 1 为最大值。不指定权重 q 值时,默认权重为 q=1.0。
当服务器提供多种内容时,将会优先返回权重值最高的媒体类型。
q
原文是“品货低数”。在 RFC2616 定义中,此处的 q 是指 qvalue, 即 quality factor(质量系数),但经过综合考虑理解记忆的便利性后,似乎采用权主值更为稳妥。——译者注
Accept-Charset
Accept-Charset 首部字段可用来告知服务器用户代理支持的字符集及字符集的相对优先顺序。另外,可一次性指定多种字符集。与首部字段 Accept 相同的是可用权重 q 值来表示相对优先级。
该首部字段应用于内容协商机制的服务器驱动协商。
Accept-Charset: iso-8859-5, unicode-1-1; q=0.8
Accept-Encoding
Accept-Encoding 首部字段用来告知服务器用户代理支持的内容编码及内容编码的优先级顺序。可一次性指定多种内容编码。
Accept-Encoding: gzip, deflate
下面试举几个内容编码的例子:
- gzip: 由文件压缩程序 gzip(GNU zip)生成的编码格式(RFC1952),采用 Lempel-Ziv 算法(LZ77)及 32 位循环冗余校验(Cyclic RedundancyCheck,通称 CRC)。
🔔 提示
gzip 是一种压缩文件格式并且也是一个在类 Unix 上的一种文件解压缩的软件。
通常指 GNU 计划的实现,此处的 gzip 代表 GNU zip。也经常用来表示 gzip 这种文件格式。软件的作者是 Jean-loup Gailly 和 Mark Adler。
在 1992 年 10 月 31 日第一次公开发布,版本号 0.1,1993年2月,发布了 1.0 版本。
compress:由 UNIX 文件压缩程序 compress 生成的编码格式,采用 Lempel-Ziv-Welch 算法(LZW)。
deflate:由文件压缩程序 zlib 生成的编码格式,采用 DEFLATE 算法。
identity:不执行压缩或不会变化的默认编码格式。 采用权重 q 值来表示相对优先级,这点与首部字段 Accept 相同。另外,也可使用星号(*)作为通配符,指定任意的编码格式。
Accept-Language
首部字段 Accept-Language 用来告知服务器用户代理能够处理的自然语言集(指中文或英文等),以及自然语言集的相对优先级。可一次指定多种自然语言集。
Accept-Language: zh-cn, zh; q=0.7, en-us, en; q=0.3
和 Accept 首部字段一样,按权重值 q 来表示相对优先级。在下述图例中,客户端在服务器有中文版资源的情况下,会请求其返回中文版对应的响应,没有中文版时,则请求返回英文版响应。
Authorization
首部字段 Authorization 是用来告知服务器用户代理的认证信息(证书值)。 通常,想要通过服务器认证的用户代理会在接收到返回的 401 状态码响应后,把首部字段 Authorization 加入请求中。共用缓存在接收到含有 Authorization 首部字段的请求时的操作处理会略有差异。
Authorization: Basic dWVub3NlbjpwYXNzd29yZA==
有关 HTTP 访问认证及 Authorization 首部字段,稍后的章节还会详细说明。另外,读者也可参阅 RFC2616。
Expect
客户端使用首部字段 Expect 用来告知服务器期望出现的某种特定行为。因服务器无法理解客户端的期望作出回应而发生错误时,会返回状态码 417 Expectation Failed。
客户端可以利用该首部字段,写明所期望的扩展。虽然 HTTP/1.1 规范只定义了 100-continue(状态码 100 Continue 之意)。
等待状态码 100 响应的客户端在发生请求时,需要指定 Expect: 100-continue。
Expect: 100-continue
From
首部字段 From 用来告知服务器使用用户代理的用户的电子邮件地址。通常,其使用目的就是为了显示搜索引擎等用户代理的负责人的电子邮件联系方式。 使用代理时,应尽可能包含 From 首部字段(但可能会因代理不同,将电子邮件地址记录在 User-Agent 首部字段内)。
Host
首部字段 Host 用于告知服务器请求的资源所处的互联网主机名和端口号。Host 首部字段在 HTTP/1.1 规范内是唯一一个必须被包含在请求内的首部字段。
Host: www.hackr.jp
图:虚拟主机运行在同一个 IP 上,因此使用首部字段 Host 加以区分
首部字段 Host 和以单台服务器分配多个域名的虚拟主机的工作机制有很密切的关联,这是首部字段 Host 必须存在的意义。
请求被发送至服务器时,请求中的主机名会用 IP 地址直接替换解决。但如果这时,相同的 IP 地址下部署运行着多个域名,那么服务器就会无法理解究竟是哪个域名对应的请求。 因此,就需要使用首部字段 Host 来明确指出请求的主机名。若服务器未设定主机名,那直接发送一个空值即可。如下所示。
Host:
If-Match
形如 If-xxx 这种样式的请求首部字段,都可称为条件请求。
If-Match 是服务器在接收到请求后进行条件判断,只有条件成立(ETag 匹配),才会继续处理请求,否则返回 412(Precondition Failed,先决条件失败)响应。
If-Match: "123456"
图:只有当 If-Match 的字段值跟 ETag 值匹配一致时,服务器才会接受请求
首部字段 If-Match,属附带条件之一,它用于告知服务器匹配资源所用的实体标记(ETag)值。这时的服务器无法使用弱 ETag 值。(请参照本章有关首部字段 ETag 的说明)
服务器会比对 If-Match 的字段值和资源的 ETag 值,仅当两者一致时,才会执行请求。反之,则返回状态码 412 Precondition Failed 的响应。
还可以使用星号(*)指定 If-Match 的字段值。针对这种情况,服务器将会忽略 ETag 的值,只要资源存在就处理请求。
If-Modified-Since
首部字段 If-Modified-Since,属附带条件之一,用于告知服务器若 If-Modified-Since 字段值早于资源的更新时间,则希望能处理该请求。 而在指定 If-Modified-Since 字段值的日期时间之后,如果请求的资源都没有过更新,则返回状态码 304 Not Modified 的响应。
If-Modified-Since: Thu,15 Apr 2004 00:00:00 GMT
图:如果在 If-Modified-Since 字段指定日期时间后,资源发生了更新,服务器会接受请求
If-Modified-Since 用于确认代理或客户端拥有的本地资源的有效性。获取资源的更新日期时间,可通过确认首部字段 Last-Modified 来确定。
If-None-Match
首部字段 If-None-Match 属于附带条件之一。它和首部字段 If-Match 作用相反。用于指定 If-None-Match 字段值的实体标记(ETag)值与请求资源的 ETag 不一致时,它就告知服务器处理该请求。
图:只有在 If-None-Match 的字段值与 ETag 值不一致时,可处理该请求。与 If-Match 首部字段的作用相反
在 GET 或 HEAD 方法中使用首部字段 If-None-Match 可获取最新的资源。因此,这与使用首部字段 If-Modified-Since 时有些类似。
If-Range
首部字段 If-Range 属于附带条件之一。用于告知服务器若指定的 If-Range 字段值(ETag 值或者时间)和请求资源的 ETag 值或时间相一致时,则作为范围请求处理。反之,则返回全体资源。
下面我们思考一下不使用首部字段 If-Range 发送请求的情况。服务器端的资源如果更新,那客户端持有资源中的一部分也会随之无效,当然,范围请求作为前提是无效的。 这时,服务器会暂且以状态码 412 Precondition Failed 作为响应返回,其目的是催促客户端再次发送请求。这样一来,与使用首部字段 If-Range 比起来,就需要花费两倍的功夫。
If-Unmodified-Since
首部字段 If-Unmodified-Since 和首部字段 If-Modified-Since 的作用相反。用于告知服务器指定的请求资源只有在字段值内指定的日期时间之后,未发生更新的情况下,才能处理请求。 如果在指定日期时间后发生了更新,则以状态码 412 Precondition Failed 作为响应返回。
Max-Forwards
通过 TRACE 方法或 OPTIONS 方法,发送包含首部字段 Max-Forwards 的请求时,该字段以十进制整数形式指定可经过的服务器最大数目。 服务器在往下一个服务器转发请求之前,会将 Max-Forwards 的值减 1 后重新赋值。当服务器接收到 Max-Forwards 值为 0 的请求时,则不再进行转发,而是直接返回响应。
Max-Forwards: 10
图:每次转发数值减 1。当数值变 0 时返回响应
使用 HTTP 协议通信时,请求可能会经过代理等多台服务器。途中,如果代理服务器由于某些原因导致请求转发失败,客户端也就等不到服务器返回的响应了。对此,我们无从可知。
可以灵活使用首部字段 Max-Forwards,针对以上问题产生的原因展开调查。 由于当 Max-Forwards 字段值为 0 时,服务器就会立即返回响应,由此我们至少可以对以那台服务器为终点的传输路径的通信状况有所把握。
图:代理B到源服务器的请求失败了,但客户端不知道
图:由于未知原因,导致请求陷入代理之间的循环,但客户端不知道
Proxy-Authorization
接收到从代理服务器发来的认证质询时,客户端会发送包含首部字段 Proxy-Authorization 的请求,用于告知服务器认证所需要的信息。
Proxy-Authorization: Basic dGlwOjkpNLAGfFY5
这个行为是与客户端和服务器之间的 HTTP 访问认证相类似的,不同之处在于,认证行为发生在客户端与代理之间。 客户端与服务器之间的认证,使用首部字段 Authorization 可起到相同作用。有关 HTTP 访问认证,后面的章节会作详尽阐述。
Range
对于只需获取部分资源的范围请求,包含首部字段 Range 即可告知服务器资源的指定范围。
示例:请求获取从第5001字节至第10000字节的资源。
Range: bytes=5001-10000
接收到附带 Range 首部字段请求的服务器,会在处理请求之后返回状态码为 206 Partial Content 的响应。无法处理该范围请求时,则会返回状态码 200 OK 的响应及全部资源。
Referer
首部字段 Referer 用于告知服务器请求的原始资源的 URI。
Referer: http://www.hackr.jp/index.htm
客户端一般都会发送 Referer 首部字段给服务器。但当直接在浏览器的地址栏输入 URI,或出于安全性的考虑时,也可以不发送该首部字段。
因为原始资源的 URI 中的查询字符串可能含有 ID 和密码等保密信息,要是写进 Referer 转发给其他服务器,则有可能导致保密信息的泄露。
另外,Referer 的正确的拼写应该是 Referrer,但不知为何,大家一直沿用这个错误的拼写。
TE
首部字段 TE 用于告知服务器客户端能够处理响应的传输编码方式及相对优先级。它和首部字段 Accept-Encoding 的功能很相像,但是用于传输编码。
TE: gzip,deflate;q=0.5
首部字段 TE 除指定传输编码之外,还可以指定伴随 trailer 字段的分块传输编码的方式。应用后者时,只需把 trailers 赋值给该字段值。
TE: trailers
User-Agent
首部字段 User-Agent 用于告知服务器创建请求的浏览器和用户代理名称等信息。
User-Agent: Mozilla/5.0 (Windows NT 6.1;WOW64;rv:13.0) Gecko/20100101 Firefox/13.0.1
图: User-Agent 用于传达浏览器的种类
由网络爬虫发起请求时,有可能会在字段内添加爬虫作者的电子邮件地址。此外,如果请求经过代理,那么中间也很可能被添加上代理服务器的名称。