Skip to main content

5. Request Header Fields (请求头字段)

客户端发送请求头字段以提供有关请求上下文的更多信息、根据目标资源状态使请求成为条件性的、建议响应的首选格式、提供认证凭证或修改预期的请求处理。这些字段充当请求修饰符,类似于编程语言方法调用上的参数。

5.1. Controls (控制)

控制是指导请求特定处理的请求头字段。

5.1.1. Expect (期望)

请求中的 Expect 头字段表示服务器需要支持的一组特定行为(期望),以便正确处理此请求。本规范定义的唯一这样的期望是 100-continue。

Expect = "100-continue"

Expect 字段值不区分大小写。

接收到除 100-continue 之外的 Expect 字段值的服务器可以使用 417 (Expectation Failed) 状态码进行响应,以指示无法满足意外的期望。

100-continue 期望通知接收方,客户端即将在此请求中发送一个(可能很大的)消息主体,并希望如果方法、目标 URI 和头字段不足以导致立即成功、重定向或错误响应,则接收 100 (Continue) 临时响应。这允许客户端在实际发送之前等待指示值得发送消息主体,当消息主体很大或客户端预期可能出现错误时(例如,在首次发送状态更改方法时,没有先前验证的认证凭证),这可以提高效率。

例如:

Expect: 100-continue

发送 100-continue 期望的客户端不需要等待任何特定的时间长度;这样的客户端可以 (MAY) 继续发送消息主体,即使它还没有收到响应。此外,由于 100 (Continue) 响应不能通过 HTTP/1.0 中间体发送,这样的客户端不应该 (SHOULD NOT) 在发送消息主体之前无限期地等待。

客户端要求:

  • 客户端不得 (MUST NOT) 在不包含消息主体的请求中生成 100-continue 期望。

服务器要求:

  • 在 HTTP/1.0 请求中接收到 100-continue 期望的服务器必须 (MUST) 忽略该期望。
  • 如果服务器已经接收到对应请求的部分或全部消息主体,或者如果框架指示没有消息主体,则服务器可以 (MAY) 省略发送 100 (Continue) 响应。
  • 发送 100 (Continue) 响应的服务器必须 (MUST) 最终发送最终状态码,一旦接收并处理消息主体,除非连接过早关闭。
  • 在读取整个消息主体之前使用最终状态码响应的服务器应该 (SHOULD) 在该响应中指示它是否打算关闭连接或继续读取和丢弃请求消息(参见 [RFC7230] 的 Section 6.6)。

5.1.2. Max-Forwards (最大转发次数)

Max-Forwards 头字段为 TRACE (Section 4.3.8) 和 OPTIONS (Section 4.3.7) 请求方法提供了一种机制,用于限制请求被代理转发的次数。当客户端试图跟踪似乎在中间链失败或循环的请求时,这可能很有用。

Max-Forwards = 1*DIGIT

Max-Forwards 值是一个十进制整数,表示此请求消息可以被转发的剩余次数。

接收到包含 Max-Forwards 头字段的 TRACE 或 OPTIONS 请求的每个中间体必须 (MUST) 在转发请求之前检查并更新其值。如果接收到的值为零 (0),中间体不得 (MUST NOT) 转发请求;相反,中间体必须 (MUST) 作为最终接收方进行响应。如果接收到的 Max-Forwards 值大于零,中间体必须 (MUST) 在转发的消息中生成更新的 Max-Forwards 字段,其字段值为 a) 接收到的值减一 (1) 或 b) 接收方支持的最大值中的较小者。

接收方可以 (MAY) 忽略与任何其他请求方法一起接收的 Max-Forwards 头字段。

示例:

Max-Forwards: 10

5.2. Conditionals (条件)

HTTP 条件请求头字段 [RFC7232] 允许客户端对目标资源的状态设置前提条件,以便如果前提条件评估为假,则不会应用与方法语义对应的操作。本规范定义的每个前提条件包括从目标资源的先前表示中获得的一组验证器与所选表示的验证器的当前状态之间的比较([RFC7232] 的 Section 7.2)。因此,这些前提条件评估自客户端已知的给定状态以来目标资源的状态是否已更改。这种评估的效果取决于方法语义和条件的选择,如 [RFC7232] 的 Section 5 中所定义。

5.3. Content Negotiation (内容协商)

以下请求头字段可以由用户代理发送,以参与响应内容的主动协商,如 Section 3.4.1 中所定义。在这些字段中发送的偏好适用于响应中的任何内容,包括目标资源的表示、错误或处理状态的表示,甚至可能出现在协议中的杂项文本字符串。

5.3.1. Quality Values (质量值)

主动协商的许多请求头字段使用一个名为 "q"(不区分大小写)的公共参数,为该关联类型内容的偏好分配相对"权重"。此权重称为"质量值"(或 "qvalue"),因为相同的参数名称通常在服务器配置中用于为可以为资源选择的各种表示的质量分配权重。

权重被标准化为 0 到 1 范围内的实数,其中 0.001 是最不优先的,1 是最优先的;值 0 表示"不可接受"。如果不存在 "q" 参数,则默认权重为 1。

weight = OWS ";" OWS "q=" qvalue
qvalue = ( "0" [ "." 0*3DIGIT ] )
/ ( "1" [ "." 0*3("0") ] )

qvalue 的发送方不得 (MUST NOT) 在小数点后生成超过三位数字。这些值的用户配置应该以相同的方式受到限制。

示例:

Accept: text/html;q=1, application/json;q=0.8
Accept-Language: en-US;q=0.9, fr;q=0.7

5.3.2. Accept (接受)

Accept 头字段可以由用户代理使用,以指定可接受的响应媒体类型。Accept 头字段可用于指示请求特别限于一小组所需类型,如对内联图像的请求的情况。

Accept = #( media-range [ accept-params ] )

media-range = ( "*/*"
/ ( type "/" "*" )
/ ( type "/" subtype )
) *( OWS ";" OWS parameter )
accept-params = weight *( accept-ext )
accept-ext = OWS ";" OWS token [ "=" ( token / quoted-string ) ]

星号 "" 字符用于将媒体类型分组为范围,"/" 表示所有媒体类型,"type/" 表示该类型的所有子类型。media-range 可以包括适用于该范围的媒体类型参数。

每个 media-range 后面可以跟随零个或多个适用的媒体类型参数(例如,charset)、用于指示相对权重的可选 "q" 参数(Section 5.3.1),然后是零个或多个扩展参数。如果存在任何扩展 (accept-ext),则需要 "q" 参数,以便它们不会被误认为是媒体类型参数。

示例

Accept: audio/*; q=0.2, audio/basic

被解释为"我更喜欢 audio/basic,但如果在质量降低 80% 后它是最好的可用,请发送给我任何音频类型。"

一个更复杂的示例是

Accept: text/plain; q=0.5, text/html,
text/x-dvi; q=0.8, text/x-c

口头上,这将被解释为"text/html 和 text/x-c 是同等优先的媒体类型,但如果它们不存在,则发送 text/x-dvi 表示,如果那也不存在,则发送 text/plain 表示。"

媒体范围可以被更具体的媒体范围或特定媒体类型覆盖。如果多个媒体范围适用于给定类型,则最具体的引用具有优先权。例如,

Accept: text/*, text/plain, text/plain;format=flowed, */*

具有以下优先级:

  1. text/plain;format=flowed
  2. text/plain
  3. text/*
  4. /

与给定类型关联的媒体类型质量因子通过找到与类型匹配的优先级最高的媒体范围来确定。例如,

Accept: text/*;q=0.3, text/html;q=0.7, text/html;level=1,
text/html;level=2;q=0.4, */*;q=0.5

将导致关联以下值:

媒体类型质量值
text/html;level=11
text/html0.7
text/plain0.3
image/jpeg0.5
text/html;level=20.4
text/html;level=30.7

注意: 用户代理可能会为某些媒体范围提供默认的质量值集。但是,除非用户代理是无法与其他渲染代理交互的封闭系统,否则此默认集应该可由用户配置。

5.3.3. Accept-Charset (接受字符集)

Accept-Charset 头字段可以由用户代理发送,以指示文本响应内容中可接受的字符集。此字段允许能够理解更全面或特殊用途字符集的用户代理向能够以这些字符集表示信息的源服务器发出该能力的信号。

Accept-Charset = 1#( ( charset / "*" ) [ weight ] )

字符集名称在 Section 3.1.1.2 中定义。用户代理可以 (MAY) 为每个字符集关联一个质量值,以指示用户对该字符集的相对偏好,如 Section 5.3.1 中所定义。示例如下:

Accept-Charset: iso-8859-5, unicode-1-1;q=0.8

特殊值 "",如果出现在 Accept-Charset 字段中,则匹配 Accept-Charset 字段中其他地方未提及的每个字符集。如果 Accept-Charset 字段中不存在 "",则字段中未明确提及的任何字符集对客户端都被视为"不可接受"。

没有任何 Accept-Charset 头字段的请求意味着用户代理将接受响应中的任何字符集。大多数通用用户代理不发送 Accept-Charset,除非特别配置为这样做,因为详细的支持字符集列表使服务器更容易通过不寻常(本地化)的偏好来识别个人。

如果请求中存在 Accept-Charset 头字段,并且响应的可用表示都没有列为可接受的字符集,则源服务器可以通过发送 406 (Not Acceptable) 响应来遵守头字段,或者通过将资源视为不受内容协商约束来忽略头字段。

5.3.4. Accept-Encoding (接受编码)

Accept-Encoding 头字段可以由用户代理使用,以指示响应中可接受的响应内容编码 (Section 3.1.2.1)。"identity" 令牌用作"无编码"的同义词,以便在不希望编码时进行通信。

Accept-Encoding  = #( codings [ weight ] )
codings = content-coding / "identity" / "*"

每个 codings 值可以 (MAY) 被赋予一个关联的质量值(权重),表示对该编码的偏好,如 Section 5.3.1 中所定义。Accept-Encoding 字段中的星号 "*" 符号匹配头字段中未明确列出的任何可用内容编码。

示例:

Accept-Encoding: compress, gzip
Accept-Encoding:
Accept-Encoding: *
Accept-Encoding: compress;q=0.5, gzip;q=1.0
Accept-Encoding: gzip;q=1.0, identity; q=0.5, *;q=0

没有 Accept-Encoding 头字段的请求意味着用户代理对内容编码没有偏好。尽管这允许服务器在响应中使用任何内容编码,但这并不意味着用户代理将能够正确处理所有编码。

服务器使用以下规则测试给定表示的内容编码是否可接受:

  1. 如果请求中没有 Accept-Encoding 字段,则用户代理认为任何内容编码都是可接受的。

  2. 如果表示没有内容编码,则默认情况下它是可接受的,除非被 Accept-Encoding 字段明确排除,该字段声明"identity;q=0"或"*;q=0"而没有更具体的"identity"条目。

  3. 如果表示的内容编码是 Accept-Encoding 字段中列出的内容编码之一,则它是可接受的,除非它伴随着 qvalue 为 0。(如 Section 5.3.1 中所定义,qvalue 为 0 表示"不可接受"。)

  4. 如果多个内容编码是可接受的,则优先选择具有最高非零 qvalue 的可接受内容编码。

具有空的组合字段值的 Accept-Encoding 头字段意味着用户代理不希望响应中有任何内容编码。如果请求中存在 Accept-Encoding 头字段,并且响应的可用表示都没有列为可接受的内容编码,则源服务器应该 (SHOULD) 发送没有任何内容编码的响应。

注意: 大多数 HTTP/1.0 应用程序不识别或不遵守与内容编码关联的 qvalue。这意味着 qvalue 可能不起作用,并且不允许与 x-gzip 或 x-compress 一起使用。

5.3.5. Accept-Language (接受语言)

Accept-Language 头字段可以由用户代理使用,以指示响应中首选的自然语言集。语言标签在 Section 3.1.3.1 中定义。

Accept-Language = 1#( language-range [ weight ] )
language-range =
<language-range, see [RFC4647], Section 2.1>

每个 language-range 可以被赋予一个关联的质量值,表示用户对该范围指定的语言的偏好的估计,如 Section 5.3.1 中所定义。例如,

Accept-Language: da, en-gb;q=0.8, en;q=0.7

意思是:"我更喜欢丹麦语,但也会接受英式英语和其他类型的英语。"

没有任何 Accept-Language 头字段的请求意味着用户代理将接受响应中的任何语言。如果请求中存在头字段,并且响应的可用表示都没有匹配的语言标签,则源服务器可以通过将资源视为不受内容协商约束来忽略头字段,或者通过发送 406 (Not Acceptable) 响应来遵守头字段。但是,不建议后者,因为这样做可能会阻止用户访问他们可能能够使用的内容(例如,使用翻译软件)。

请注意,一些接收方将语言标签列出的顺序视为降序优先级的指示,特别是对于分配了相等质量值的标签(无值与 q=1 相同)。但是,不能依赖这种行为。为了一致性并最大化互操作性,许多用户代理为每个语言标签分配唯一的质量值。

有关语言优先级列表的其他讨论可以在 [RFC4647] 的 Section 2.3 中找到。

5.4. Authentication Credentials (认证凭证)

两个头字段用于携带认证凭证,如 HTTP 认证 [RFC7235] 中所定义。请注意,各种自定义用户认证机制为此目的使用 Cookie 头字段,如 [RFC6265] 中所定义。

5.4.1. Authorization (授权)

Authorization 头字段允许用户代理向源服务器验证自己——通常但不一定在收到 401 (Unauthorized) 响应后。其值由包含用户代理对所请求资源的域的认证信息的凭证组成。

Authorization = credentials

如果请求经过认证并指定了域,则假定相同的凭证对此域内的所有其他请求有效(假设认证方案本身不要求其他方式,例如根据挑战值而变化的凭证或使用同步时钟)。

转发请求的代理不得 (MUST NOT) 修改该请求中的任何 Authorization 字段。有关详细信息,请参见 [RFC7235] 的 Section 3.2。

为了让用户代理发送包含密码的凭证,它必须知道与源服务器的连接是安全的。有关相关安全考虑,请参见 Section 9.4。

5.4.2. Proxy-Authorization (代理授权)

Proxy-Authorization 头字段允许客户端向需要认证的代理标识自己(或其用户)。其值由包含客户端对代理和/或所请求资源的域的认证信息的凭证组成。

Proxy-Authorization = credentials

Authorization 不同,Proxy-Authorization 头字段仅适用于使用 Proxy-Authenticate 字段要求认证的下一个入站代理。当链中使用多个代理时,Proxy-Authorization 头字段由期望接收凭证的第一个入站代理消费。如果这是代理协作认证给定请求的机制,代理可以 (MAY) 将凭证从客户端请求中继到下一个代理。

5.5. Request Context (请求上下文)

以下请求头字段提供有关请求上下文的其他信息,包括有关请求背后的用户、用户代理和资源的信息。

5.5.1. From (来自)

From 头字段包含控制请求用户代理的人类用户的互联网电子邮件地址。该地址应该是机器可用的,如 [RFC5322] 的 Section 3.4 中的"mailbox"所定义。

From = mailbox

示例如下:

From 头字段很少由非机器人用户代理发送。用户代理不应该 (SHOULD NOT) 在没有用户明确配置的情况下发送 From 头字段,因为这可能与用户的隐私利益或其站点的安全策略冲突。

机器人用户代理应该 (SHOULD) 发送有效的 From 头字段,以便在服务器上发生问题时可以联系负责运行机器人的人,例如如果机器人发送过多、不需要或无效的请求。

服务器不应该 (SHOULD NOT) 使用 From 头字段进行访问控制或认证,因为大多数接收方会假设字段值是公共信息。

5.5.2. Referer (引用者)

Referer [原文如此] 头字段允许用户代理为获取目标 URI 的资源指定 URI 引用(即,"referrer"(引用者),尽管字段名称拼写错误)。用户代理在生成 Referer 字段值时,不得 (MUST NOT) 包含 URI 引用 [RFC3986] 的片段和用户信息组件(如果有)。

Referer = absolute-URI / partial-URI

Referer 头字段允许服务器生成到其他资源的反向链接,用于简单的分析、日志记录、优化缓存等。它还允许找到过时或拼写错误的链接以进行维护。一些服务器使用 Referer 头字段作为拒绝来自其他站点的链接(所谓的"深度链接")或限制跨站请求伪造 (CSRF) 的手段,但并非所有请求都包含它。

示例:

Referer: http://www.example.org/hypertext/Overview.html

如果目标 URI 是从没有自己的 URI 的来源获得的(例如,来自用户键盘的输入,或用户书签/收藏夹中的条目),则用户代理必须 (MUST) 排除 Referer 字段或使用值"about:blank"发送它。

如果引用资源的标识符揭示了个人信息(例如帐户名称)或应该保密的资源(例如防火墙后或受保护服务内部),则 Referer 字段有可能揭示有关请求上下文或用户浏览历史记录的信息,这是一个隐私问题。大多数通用用户代理在引用资源是本地"file"或"data" URI 时不发送 Referer 头字段。如果引用页面是使用安全协议接收的,则用户代理不得 (MUST NOT) 在不安全的 HTTP 请求中发送 Referer 头字段。有关其他安全考虑,请参见 Section 9.4。

已知一些中间体会不加区分地从出站请求中删除 Referer 头字段。这具有干扰针对 CSRF 攻击的保护的不幸副作用,这对他们的用户可能更有害。希望限制 Referer 中信息披露的中间体和用户代理扩展应该将其更改限制为特定编辑,例如用假名替换内部域名或截断查询和/或路径组件。当字段值与请求目标共享相同的方案和主机时,中间体不应该 (SHOULD NOT) 修改或删除 Referer 头字段。

5.5.3. TE (传输编码)

TE 头字段指示除了分块之外,客户端愿意在响应中接受哪些传输编码,以及客户端是否愿意在分块传输编码中接受尾部字段。

TE 字段值由以逗号分隔的传输编码名称列表组成,每个都允许可选参数(如 [RFC7230] 的 Section 4 中所述),和/或关键字"trailers"。

TE        = #( t-codings )
t-codings = "trailers" / ( transfer-coding [ t-ranking ] )
t-ranking = OWS ";" OWS "q=" rank
rank = ( "0" [ "." 0*3DIGIT ] )
/ ( "1" [ "." 0*3("0") ] )

以下是 TE 使用的三个示例。

TE: deflate
TE:
TE: trailers, deflate;q=0.5

TE 头字段仅适用于直接连接。因此,每当 TE 出现在 HTTP/1.1 消息中时,必须 (MUST) 在 Connection 头字段([RFC7230] 的 Section 6.1)中提供关键字"TE"。

服务器使用与 Accept-Encoding (Section 5.3.4) 相同的规则测试传输编码是否可接受,除了名为"trailers"的编码始终可接受,并且带有"q"参数值为 0 的传输编码不可接受。

由于 TE 头字段仅适用于直接连接,TE 的发送方还必须 (MUST) 在 Connection 头字段([RFC7230] 的 Section 6.1)中发送"TE"连接选项,以防止不支持其语义的中间体转发 TE 字段。

5.5.4. User-Agent (用户代理)

User-Agent 头字段包含有关发起请求的用户代理的信息,服务器通常使用它来帮助识别报告的互操作性问题的范围、解决或调整响应以避免特定的用户代理限制,以及用于浏览器或操作系统使用的分析。用户代理应该 (SHOULD) 在每个请求中发送 User-Agent 字段,除非特别配置为不这样做。

User-Agent = product *( RWS ( product / comment ) )

User-Agent 字段值由一个或多个产品标识符组成,每个后面跟随零个或多个注释([RFC7230] 的 Section 3.2),它们一起标识用户代理软件及其重要子产品。按照惯例,产品标识符按其对识别用户代理软件的重要性降序列出。每个产品标识符由名称和可选版本组成,如 [RFC7230] 的 Section 5.5.3 中所定义。

示例:

User-Agent: CERN-LineMode/2.15 libwww/2.17b3

用户代理不应该 (SHOULD NOT) 生成包含不必要细粒度细节的 User-Agent 字段,并且应该 (SHOULD) 限制第三方添加子产品。过长和详细的 User-Agent 字段值会增加请求延迟和用户被违背意愿识别的风险("指纹识别")。

同样,鼓励实现不要使用其他实现的产品令牌来声明与它们的兼容性,因为这违背了该字段的目的。如果用户代理伪装成不同的用户代理,接收方可以假设用户有意希望看到为该已识别用户代理定制的响应,即使它们可能不适合实际使用的用户代理。