实体主体是否允许HTTP DELETE请求?

http rest

290070 观看

12回复

45450 作者的声誉

发出HTTP DELETE请求时,请求URI应完全标识要删除的资源。但是,是否允许添加额外的元数据作为请求的实体主体的一部分?

作者: Haacked 的来源 发布者: 2008 年 11 月 18 日

回应 (12)


465

258624 作者的声誉

决定

该规范没有明确禁止或阻止它,所以我倾向于说它是允许的。

微软以同样的方式看待它(我可以听到观众中的嘀咕声),他们在MSDN文章中指出ADO.NET数据服务框架DELETE方法

如果DELETE请求包含实体主体,则忽略正文[...]

另外这里是RFC2616(HTTP 1.1)对请求的说法:

  • 一个实体主体是仅当存在时一个消息体存在(第7.2部分)
  • 通过包含a 或标题来表示消息体的存在(第4.3节)Content-LengthTransfer-Encoding
  • 一个消息体必须不被包括在所述请求的方法的规范不允许发送实体主体(第4.3节)
  • 一个实体主体仅在TRACE请求明确禁止,所有其它请求类型是不受限制的(第9节和9.8特异性)

对于回复,这已经定义:

  • 是否包含消息正文取决于请求方法响应状态(第4.3节)
  • 一个消息体在以HEAD请求的响应明确禁止(第9节,和9.4特异性)
  • 一个消息体被明确禁止在1XX(信息),204(无内容),和304(未修饰的)反应(第4.3节)
  • 所有其他响应都包含一个消息体,尽管它可能是零长度(第4.3节)
作者: Tomalak 发布者: 18.11.2008 06:36

27

307363 作者的声誉

在我看来,RFC 2616没有指定这一点。

从第4.3节:

通过在请求的消息头中包含Content-Length或Transfer-Encoding头字段来指示请求中消息体的存在。如果请求方法的规范(第5.1.1节)不允许在请求中发送实体主体,则消息主体不得包含在请求中。服务器应该在任何请求上读取和转发消息体; 如果请求方法不包含实体主体的定义语义,那么在处理请求时应该忽略消息主体。

第9.7节:

DELETE方法请求源服务器删除Request-URI标识的资源。可以通过源服务器上的人为干预(或其他方式)覆盖此方法。即使从源服务器返回的状态代码表明操作已成功完成,也无法保证客户端已执行该操作。但是,服务器不应该指示成功,除非在给出响应时,它打算删除资源或将其移动到不可访问的位置。

如果响应包括描述状态的实体,则成功响应应为200(OK),如果操作尚未执行,则应为202(已接受);如果操作已颁布但响应不包括,则应为204(无内容)一个实体。

如果请求通过缓存并且Request-URI标识了一个或多个当前缓存的实体,那么这些条目应该被视为陈旧。对此方法的响应不是cacheable.c

所以它没有被明确允许或禁止,并且沿途的代理可能会删除消息体(尽管它应该读取并转发它)。

作者: Adam Rosenfield 发布者: 18.11.2008 06:37

52

786 作者的声誉

某些版本的Tomcat和Jetty似乎忽略了实体主体(如果存在)。如果您打算收到它可能会令人讨厌。

作者: evan.leonard 发布者: 15.01.2010 07:56

132

1449 作者的声誉

HTTP 1.1规范(RFC 7231)的最新更新明确允许DELETE请求中的实体主体:

DELETE请求消息中的有效负载没有定义的语义; 在DELETE请求上发送有效负载主体可能会导致某些现有实现拒绝该请求。

作者: grzes 发布者: 04.04.2012 04:49

7

52892 作者的声誉

ElasticSearch似乎使用了这个:https://www.elastic.co/guide/en/elasticsearch/reference/5.x/search-request-scroll.html#_clear_scroll_api

这意味着Netty支持这一点。

就像在评论中提到的那样可能不再是这种情况了

作者: Sebastien Lorber 发布者: 27.05.2013 02:59

44

33682 作者的声誉

在删除请求中使用正文的一个原因是乐观并发控制。

您阅读了记录的第1版。

GET /some-resource/1
200 OK { id:1, status:"unimportant", version:1 }

您的同事阅读记录的第1版。

GET /some-resource/1
200 OK { id:1, status:"unimportant", version:1 }

您的同事更改记录并更新数据库,将版本更新为2:

PUT /some-resource/1 { id:1, status:"important", version:1 }
200 OK { id:1, status:"important", version:2 }

您尝试删除记录:

DELETE /some-resource/1 { id:1, version:1 }
409 Conflict

您应该获得乐观的锁定异常。重新阅读记录,看它是重要的,也许不能删除它。

使用它的另一个原因是一次删除多个记录(例如,带有行选择复选框的网格)。

DELETE /messages
[{id:1, version:2},
{id:99, version:3}]
204 No Content

请注意,每条消息都有自己的版本。也许你可以使用多个标题来指定多个版本,但是通过George,这更简单,更方便。

这适用于Tomcat(7.0.52)和Spring MVC(4.05),也可能是早期版本:

@RestController
public class TestController {

    @RequestMapping(value="/echo-delete", method = RequestMethod.DELETE)
    SomeBean echoDelete(@RequestBody SomeBean someBean) {
        return someBean;
    }
}
作者: Neil McGuigan 发布者: 09.08.2013 06:24

3

31 作者的声誉

如果有人遇到此问题测试,请不要普遍支持。

我目前正在使用Sahi Pro进行测试,很明显一个http DELETE调用剥离任何提供的正文数据(根据端点设计批量删除大量的id)。

我已多次与他们联系,并发送三个单独的包裹,图像,日志包供他们审查,他们仍然没有证实这一点。一个失败的补丁,以及之后他们的支持错过了电话会议,我仍然没有得到一个可靠的答案。

我确信Sahi不支持这个,我会想象许多其他工具都可以使用套件。

作者: parker 发布者: 21.08.2015 08:29

14

1698 作者的声誉

只是抬头,如果您在DELETE请求中提供正文并使用Google云端HTTPS负载均衡器,它将拒绝您的请求,并出现400错误。我正撞在墙上,发现Google出于某种原因认为带有正文的DELETE请求是一个格式错误的请求。

作者: Ben Fried 发布者: 25.05.2016 11:46

6

125 作者的声誉

这没有定义

DELETE请求消息中的有效负载没有定义的语义; 在DELETE请求上发送有效负载主体可能会导致某些现有实现拒绝该请求。
https://tools.ietf.org/html/rfc7231#page-29

作者: Simon Jin 发布者: 09.01.2017 07:43

2

6175 作者的声誉

值得注意的是,版本3.0的OpenAPI规范放弃了对具有正文的DELETE方法的支持:

这里这里的参考

这可能会影响您将来实施,记录或使用这些API。

作者: Clever Human 发布者: 09.11.2018 03:25

0

160 作者的声誉

可能是下面的GitHUb网址将帮助你,得到答案。实际上,像Tomcat这样的Application Server,Weblogic使用请求有效负载拒绝HTTP.DELETE调用。所以记住这些事情,我在github中添加了一个例子,请看一下

https://github.com/ashish720/spring-examples

作者: Ashish 发布者: 17.02.2019 04:22

0

41342 作者的声誉

虽然对现有答案有很多好评,但我认为这个问题没有得到很好的答复。我将把这些评论的要点提升到一个新的答案:

RFC7231的这一段已被引用过几次,总结起来了。

DELETE请求消息中的有效负载没有定义的语义; 在DELETE请求上发送有效负载主体可能会导致某些现有实现拒绝该请求。

我从其他答案中遗漏的是暗示。是的,允许在DELETE请求中包含一个正文,但它在语义上毫无意义。这实际上意味着发出DELETE请求主体的请求在语义上等同于不包括请求主体。

包括请求主体不应该对请求产生任何影响,因此包含它永远不会有任何意义。

tl; dr:从技术上讲DELETE,允许使用请求正文的请求,但这样做绝对没用。

作者: Evert 发布者: 17.02.2019 04:35
32x32