为什么对PUT请求的响应必须不提供ETag?

sp0*_*00m 4 rest etag http put rfc

超文本传输​​协议(HTTP / 1.1):语义和内容

原始服务器绝不能在成功响应中发送验证器头字段第7.2节),例如ETagLast-Modified字段,PUT除非保存请求的表示数据而未对主体应用任何转换(即资源的新表示数据相同) (表示为PUT请求中收到的表示形式数据),并且验证者字段值反映了新的表示形式。由于的要求,此要求允许用户代理知道其在内存中的表示主体何时保持最新状态PUT,从而无需再次从源服务器检索,并且响应中收到的新验证器可以用于将来的条件请求为了防止意外覆盖(第5.2节)。

我不能完全理解本节...粗体的句子似乎相互矛盾,不是吗?

请注意,这PUT是唯一具有与验证程序标题有关的部分的动词(请参阅GET/ POST/ DELETE/ PATCH)。

Kev*_*nry 5

关键是服务器可以或可以不更改表示形式然后再存储它。在您链接到的部分中:

PUT给定表示的成功表示GET,同一目标资源上的后续表示将导致在200 (OK)响应中发送等效表示。但是,不能保证这种状态变化是可观察到的,因为目标...可能会受到源服务器的动态处理。

因此,该标准使用是否存在验证器头来向用户代理指示表示是否已更改。

如果表示未更改,则服务器可以返回验证器头字段,并且用户代理可以使用该字段有条件地验证刚刚发送的表示。

如果表示已更改,那么根据定义,用户代理的表示无效。因此,不会返回任何验证程序头,并且用户代理将必须执行无条件的GET

  • 谢谢,还有一个问题:客户端有一个资源版本,修改它,将它发送到服务器,服务器应用额外的修改并将新的表示返回给客户端。在这种情况下,请求的正文!= 响应的正文。为什么服务器不能直接在响应中提供新的 ETag?然后客户端可以检查其本地 ETag 是否与响应中的匹配,并相应地更新其缓存。这将避免客户端再次获取资源(该响应将具有与 PUT 响应完全相同的主体,但这次使用 ETag)... (2认同)
  • @sp00m:我认为这里的混淆在于您假设服务器将响应正文中的表示发送回`PUT`。但事实并非如此。如果您控制服务器,那么您当然可以做到,但这不是标准的一部分。所以一般来说,如果不执行新的(无条件的)`GET`,用户代理就无法知道新的表示。 (2认同)
  • 您可能想看看http://greenbytes.de/tech/webdav/rfc7240.html#return (2认同)