多年来,许多人对此表示怀疑,正如我们在此处的相关问题中看到的那样。似乎接受的答案范围从“一定会这样做" to "它明显滥用了协议由于很多问题都是几年前发出的,所以让我们从 2014 年 6 月开始深入研究 HTTP 1.1 规范(RFC 7231 https://www.rfc-editor.org/rfc/rfc7231),以便更好地了解明确不鼓励或不鼓励的内容。
第一个建议的解决方法:
首先,关于资源和 URI 本身第2节 https://www.rfc-editor.org/rfc/rfc7231#section-2:
HTTP 请求的目标称为“资源”。 HTTP 不限制资源的性质;它仅仅定义了一个可用于与资源交互的接口。每个资源都由统一资源标识符 (URI) 标识。
基于此,有些人可能会争辩说,由于 HTTP 不限制资源的性质,因此包含多个资源的 URIid
将是可能的。我个人认为这是一个解释问题。
关于您提出的第一个解决方法(DELETE '/path/abc?itemId=1&itemId=2&itemId=3'
)我们可以得出这样的结论:如果您将资源视为实体集合中的单个文档,那么这是令人沮丧的事情,而如果您将资源视为实体集合本身,则可以很好地进行。
第二个建议的解决方法:
关于您提出的第二个解决方法(POST '/path/abc' with body: { ids: [1, 2, 3] }
), 使用POST
删除方法可能会产生误导。这部分第 4.3.3 节 https://www.rfc-editor.org/rfc/rfc7231#section-4.3.3说关于POST
:
POST 方法请求目标资源根据资源自身的特定语义处理请求中包含的表示。例如,POST 用于以下功能(除其他外): 向数据处理过程提供数据块,例如输入到 HTML 表单中的字段;将消息发布到公告板、新闻组、邮件列表、博客或类似的文章组;创建尚未被源服务器识别的新资源;将数据附加到资源的现有表示。
虽然对于“除其他外”的功能有一些解释空间POST
,它显然与我们有该方法的事实相冲突DELETE
用于资源移除,正如我们所见第 4.1 节 https://www.rfc-editor.org/rfc/rfc7231#section-4.1:
DELETE 方法删除目标资源的所有当前表示。
所以我个人强烈反对使用POST
删除资源。
另一种解决方法:
受到您的第二种解决方法的启发,我们建议另一种解决方法:
DELETE '/path/abc' with body: { ids: [1, 2, 3] }
它与解决方法二中建议的几乎相同,但使用正确的 HTTP 方法进行删除。在这里,我们遇到了使用实体的困惑body
in a DELETE
要求。有很多人说它无效,但我们还是坚持一下吧第 4.3.5 节 https://www.rfc-editor.org/rfc/rfc7231#section-4.3.5规格:
DELETE 请求消息中的有效负载没有定义的语义;在 DELETE 请求上发送有效负载正文可能会导致某些现有实现拒绝该请求。
因此,我们可以得出结论,该规范不会阻止DELETE
从有一个body
有效负载。不幸的是,一些现有的实现可能会拒绝该请求......但这对我们今天有何影响?
很难百分百确定,但现代的要求是fetch
只是不允许body
for GET
and HEAD
。这就是什么获取标准 https://fetch.spec.whatwg.org/状态于第 5.3 节 https://fetch.spec.whatwg.org/#request-class关于第 34 项:
如果 body 存在且非 null 或 inputBody 非 null,并且请求的方法是 GET 或 HEAD,则抛出 TypeError。
我们可以确认它是以相同的方式实现的获取polyfill https://github.com/github/fetch at line 342 https://github.com/github/fetch/blob/3674c98df696d45573750aa7873814887d25689a/fetch.js#L342.
最后的想法:
由于替代解决方法是DELETE
and a body
HTTP 规范允许有效负载可行,并且所有现代浏览器都支持fetch
从 IE10 开始,我建议使用这种方式以有效且完整的工作方式进行批量删除。