Skip to content

Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests

1. Introduction

HTTP 条件请求是指包含一个或多个表示状态变化的元数据头字段的 HTTP 请求。在应用方法语义到目标资源之前,这些头字段用于指示需要测试的前提条件。本文件定义了 HTTP/1.1 条件请求机制,包括架构、语法表示法和符合性标准。

条件 GET 请求是 HTTP 缓存更新的最有效机制。条件请求也可以应用于状态改变的方法(如 PUT 和 DELETE),以防止“丢失更新”问题,即一个客户端意外覆盖另一个并行操作的客户端的工作。

条件请求前提条件基于目标资源的整体状态或先前获取的表示的状态。条件请求机制假设请求到“选定表示”的映射在时间上是一致的。如果映射不一致且服务器无法选择适当的表示,则当前提条件评估为 false 时不会造成任何损害。

2. Validators

本规范定义了两种常用的元数据形式,用于观察资源状态并测试前提条件:修改日期和不透明实体标签(ETag)。当元数据用于前提条件时,它被称为“验证器”。

2.1 Weak versus Strong

验证器分为强弱两种。弱验证器易于生成但比较时不太有用。强验证器理想用于比较,但生成起来可能非常困难。HTTP 暴露了所使用的验证器类型,并规定了弱验证器的使用限制。

  • 强验证器:每当表示数据发生可观察变化时,强验证器的值会改变。
  • 弱验证器:值可能不会随每次表示数据的变化而改变。

2.2 Last-Modified

“Last-Modified”响应头字段提供了一个时间戳,指示原服务器认为选定表示最后一次修改的日期和时间。

2.3 ETag

“ETag”响应头字段提供了选定表示的当前实体标签。实体标签是用于区分同一资源的多个表示的验证器。实体标签可以是弱验证器或强验证器,默认情况下是强验证器。

3. Precondition Header Fields

本节定义了 HTTP/1.1 头字段的语法和语义,用于在请求上应用前提条件。

3.1 If-Match

“If-Match”头字段使请求方法在接收方服务器具有目标资源的当前表示时才执行。服务器必须使用强比较函数来比较实体标签。

3.2 If-None-Match

“If-None-Match”头字段使请求方法在接收方缓存或服务器没有目标资源的当前表示时才执行。接收方必须使用弱比较函数来比较实体标签。

3.3 If-Modified-Since

“If-Modified-Since”头字段使 GET 或 HEAD 请求方法在选定表示的修改日期晚于提供的日期时才执行。

3.4 If-Unmodified-Since

“If-Unmodified-Since”头字段使请求方法在选定表示的最后修改日期早于或等于提供的日期时才执行。用于防止意外覆盖。

3.5 If-Range

“If-Range”头字段提供了一种特殊的条件请求机制,类似于 If-Match 和 If-Unmodified-Since,但指示接收方在验证器不匹配时忽略 Range 头字段。

4. Status Code Definitions

4.1 304 Not Modified

304 状态码指示条件 GET 或 HEAD 请求已被接收,并且如果不是因为条件评估为 false,将会导致 200(OK)响应。这表明服务器无需传输目标资源的表示。

4.2 412 Precondition Failed

412 状态码指示请求头字段中给定的一个或多个条件在服务器上测试为 false。这允许客户端在当前资源状态上设置前提条件,从而防止请求方法在目标资源处于意外状态时被应用。

5. Evaluation

接收方缓存或服务器必须在成功执行正常请求检查后、执行请求方法相关的操作之前评估接收到的请求前提条件。

6. Precedence

当请求中存在多个条件请求头字段时,字段的评估顺序变得重要。接收方缓存或服务器必须按照以下顺序评估请求前提条件:

  1. 如果接收方是原服务器且存在 If-Match,则评估 If-Match 前提条件。
  2. 如果接收方是原服务器且不存在 If-Match,但存在 If-Unmodified-Since,则评估 If-Unmodified-Since 前提条件。
  3. 如果存在 If-None-Match,则评估 If-None-Match 前提条件。
  4. 如果方法是 GET 或 HEAD 且不存在 If-None-Match,但存在 If-Modified-Since,则评估 If-Modified-Since 前提条件。
  5. 如果方法是 GET 且同时存在 Range 和 If-Range,则评估 If-Range 前提条件。
  6. 否则,所有条件都满足,执行请求的操作并根据其成功或失败进行响应。

ABNF

abnf
ETag = entity-tag

HTTP-date = <HTTP-date, see [RFC7231], Section 7.1.1.1>

If-Match = "*" / ( *( "," OWS ) entity-tag *( OWS "," [ OWS entity-tag ] ) )
If-Modified-Since = HTTP-date
If-None-Match = "*" / ( *( "," OWS ) entity-tag *( OWS "," [ OWS entity-tag ] ) )
If-Unmodified-Since = HTTP-date

Last-Modified = HTTP-date

OWS = <OWS, see [RFC7230], Section 3.2.3>

entity-tag = [ weak ] opaque-tag
etagc = "!" / %x23-7E ; '#'-'~' / obs-text

obs-text = <obs-text, see [RFC7230], Section 3.2.6>
opaque-tag = DQUOTE *etagc DQUOTE

weak = %x57.2F ; W/