25

假设我想实现某种乐观锁定并使用 ETags 来指示最新的资源状态。这意味着,客户端在进行更新时将使用If-Match标头。PUT

根据HTTP 规范412 Precondition failed,如果为标头提供的 ETagIf-Match与资源的当前状态不匹配,则服务器必须返回。

但是,409 Conflict似乎更接近我想要在语义上表达的内容,特别是因为它给出了在响应中包含的内容的指南。

409如果无法匹配标头中提供的 ETag ,宁愿返回是不是非常错误If-Match

4

1 回答 1

38

从您到规范的链接:

如果没有一个实体标签匹配,或者如果给出了“*”并且没有当前实体存在,服务器不能执行请求的方法,并且必须返回一个 412(Precondition Failed)响应。当客户端想要阻止更新方法(例如 PUT)修改自客户端上次检索后已更改的资源时,此行为最有用。

因为规范需要 HTTP 412(实际上它使用“MUST”),并且很明显它们准确地解释了正在讨论的用例,所以 HTTP 412 似乎是正确的响应代码。

无论如何,412是相当合理的。该请求说有条件地进行更新。412 表示条件失败,因此服务不会执行此操作。尤其是因为 412 非常适合条件请求的概念;409 似乎与特定类型的拒绝有关,这可能是有条件的,也可能不是有条件的。例如,我可以看到服务返回 409 以响应无条件请求 POST 具有内部冲突的内容。

但请参阅以下内容,也来自规范:

10.4.10 409 冲突

由于与资源的当前状态冲突,无法完成请求。仅在预期用户可能能够解决冲突并重新提交请求的情况下才允许使用此代码。响应正文应该包含足够的信息让用户识别冲突的来源。理想情况下,响应实体将包含足够的信息供用户或用户代理解决问题;但是,这可能是不可能的,也不是必需的。

响应 PUT 请求时最有可能发生冲突。例如,如果正在使用版本控制并且被 PUT 的实体包括对资源的更改,这些更改与早期(第三方)请求所做的更改相冲突,则服务器可能会使用 409 响应来指示它无法完成请求. 在这种情况下,响应实体可能会以响应 Content-Type 定义的格式包含两个版本之间差异的列表。

无论如何,规范似乎要求在条件请求上下文中使用 412,同时暗示版本冲突是 409 的关键驱动因素。可能会在版本冲突发生的情况下使用 409 作为无条件请求的一部分。

于 2013-10-01T20:03:26.313 回答