文章目录
  1. 1. 如何生成Last-Modified和ETag头
  2. 2. 如何在服务器端实现条件GET请求&如何从客户端提交条件GET和HEAD请求
  3. 3. 如何在服务器端实现条件PUT请求
  4. 4. 如何在服务器端实现条件DELETE请求
  5. 5. 如何从客户端发起无条件的GET请求
  6. 6. 如何从客户端提交条件PUT和DELETE请求
  7. 7. 如何使POST请求条件化&如何生成一次性URI

HTTP条件请求有助于解决两个问题。对于GET请求,条件请求帮助客户端和缓存检验缓存的表述是否新鲜。对于PUT、POST和DELETE等不安全的请求,条件请求提供了并发控制。

不支持条件GET请求会将降低性能。但对于并发,不支持条件POST、PUT和DELETE请求不安全而且可能影响应用程序完整性。缺乏足够的并发控制检查,服务器容易“丢失更新”或“陈旧删除”。当客户端它基于自认为的资源当前状态提交请求修改或删除资源,但在并发条件下,资源的当前状态并不是静态的,服务器(通过后端方式)或其他客户端都有可能已经修改或删除了资源。

并发控制确保客户端对数据的并发操作被正确处理。有两种并发控制实现方式:

  1. 悲观并发控制:锁机制。
  2. 乐观并发控制:此模式下,客户端首先获得令牌,之后在写请求中携带此令牌,如果令牌有效则操作成功,否则操作失败。HTTP以此模式工作。

如何生成Last-Modified和ETag头

服务器使用Last-Modified和ETag响应头驱动条件请求。客户端使用If-Modified-Since和If-None-Match验证缓存表述,使用If-Unmodified-Since和If-Match进行并发控制预处理。

如果对存储资源的数据存储区能够控制,修改每个资源的schema以包含用来跟踪版本的修改时戳或序列号。如果数据存储区是数据库,使用触发器在数据修改时自动更新上述字段。如果无法修改存储schema或数据存储区不允许维护时戳或序列号,使用资源数据生成ETag头数值,并存储到单独的表或存储区。如果表述不是很大,使用表述体生成MD5哈希值或每次随资源变动的某些字段用于ETag。Last-Modified是一种弱验证,ETag是一种强验证,两者不必同时使用。

如何在服务器端实现条件GET请求&如何从客户端提交条件GET和HEAD请求

如果客户端在本地存储表述体,可以将响应的Last-Modified和ETag头一同存储。客户端基于上次请求响应的Last-Modified和ETag头发送带有If-Modified-Since或If-Non-Match的条件GET请求,服务器发现表述没有改变,可以省去发送表述体仅发送状态码304 (Not Modified),否则发送包含新ETag或Last-Modified头的最新表述体。

如何在服务器端实现条件PUT请求

如何在服务器端实现条件DELETE请求

如何从客户端发起无条件的GET请求

当客户端使用条件GET请求查询失败,获得412 (Precondition Failed)状态码。HTTP 1.1允许客户端修改到期缓存、使用包含Cache-Control:no-Cache和Pragma:no-cache的无条件GET请求获取新鲜表述。

如何从客户端提交条件PUT和DELETE请求

当客户端使用PUT创建新资源时,或服务器在同一资源的上一个GET或PUT请求响应中没有返回Last-Modified或ETag头,客户端像和平时一样发送PUT请求。

如果客户端拥有之前对资源请求响应的Last-Modified和ETag头,客户端基于上次请求响应的Last-Modified和ETag头发送带有If-Unmodified-Since或If-Match的条件PUT/DELETE请求。如果服务器返回412 (Precondition Failed)状态码,客户端可通过无条件GET请求获取新鲜表述,决定是否通过重发PUT/DELETE实现自己的需求。

如何使POST请求条件化&如何生成一次性URI

与PUT或DELETE不同,对一个资源的POST请求可能不会对请求URI中的资源造成任何改变。服务器可能会创建一个新资源(状态码201)或使用不同URI(状态码303)标识输出。因此,客户端不会在本地存储表述和条件头。为了让服务器检测和防止客户端重复发送POST请求,可以通过一次性URI实现条件或不可重复的POST请求。

客户端实现通过GET请求获取包含token链接,如果URI的目的是创建新资源,基于序列号、时戳和随机数的连接串生成token。如果URI的目的是修改资源,基于这些资源的实体标签和标识符生成token。

客户端发送服务器响应中提供的一次性URI进行POST请求,服务器查看token是否已经在服务器的事务日志中存在,以检测POST请求有效性,如果存在返回状态码403 (Forbidden)并解释原因,否则根据输出返回状态码201 (Created)或303 (See Other)。

文章目录
  1. 1. 如何生成Last-Modified和ETag头
  2. 2. 如何在服务器端实现条件GET请求&如何从客户端提交条件GET和HEAD请求
  3. 3. 如何在服务器端实现条件PUT请求
  4. 4. 如何在服务器端实现条件DELETE请求
  5. 5. 如何从客户端发起无条件的GET请求
  6. 6. 如何从客户端提交条件PUT和DELETE请求
  7. 7. 如何使POST请求条件化&如何生成一次性URI