HTTP的DELET方法能不能有Body?

起因

长期以来,我基本上从事的都是移动端开发,对后台的API规范属于一知半解了,倒是以前研究过GET方法能不能有BODY,但从没想过HTTP的DELETE方法能不能有Body,毕竟我很少有用到DELETE,以至于我一直觉得DELETE支持BODY,直接到今天Calude给我上了一课,起因是我想写一个删除账号的API,要带上一个验证码,如果从RESTful规范和语义上说,用DELETE显然是更适合的,但Claude Code却建议我使用POST:

go 复制代码
1.  **`POST` 还是 `DELETE` 方法**:语义上"删除"更该用 HTTP `DELETE`,但 `DELETE` 带 body 在部分客户端/网关上支持不一致,而且现有 `signup`/`reset-password` 都是状态变更但用的 `POST`。为了跟现有风格一致、也避免 body-in-DELETE 的坑,**建议沿用 `POST`**。

也就是说DELETE方法在不同的地方对BODY的支持是不一致的,有的是支持的,有的是不支持。本着对真相的渴望,我又去问了Gemini,Gemini告诉我:"技术上可以,但极度不推荐 。根据 MDN Web Docs 的定义,HTTP 规范对DELETE 请求的 Body 没有定义明确的语义。这意味着标准允许请求带有 Body,但服务器在接收到带有 Body 的 DELETE 请求时,可以根据自身的实现自由处理(例如忽略它或直接处理)"。也就是说,你可以给DELTE加一个。而且大多数web服务器也不会明确禁止这样做。就像大多数web服务器也不会禁止GET请求带body一样。这更多的是服务端的endpoint handler和客户端使用服务的实现细节。

事实上真是这样的吗?

如果我们去查阅HTTP 协议的官方规范(RFC 9110),你会发现DELETE还真就不应该带BODY,规范原文如下:

markdown 复制代码
A client **SHOULD NOT** generate content in a DELETE request unless it is made directly to an origin server that has previously indicated, in or out of band, that such a request has a purpose and will be adequately supported. An origin server SHOULD NOT rely on private agreements to receive content, since participants in HTTP communication are often unaware of intermediaries along the request chain.

翻译一下:

markdown 复制代码
客户端**不应当**在 DELETE 请求中生成正文内容,除非该请求是直接发送给源服务器,且该服务器此前已通过带内或带外方式明确表明此类请求具有特定目的且会得到充分支持。源服务器**不应当**依赖私下协议来接收正文内容,因为 HTTP 通信的参与者通常无法察觉请求链中存在的中间件(如代理服务器等)。

SHOULD NOT本身不是禁止的意思,也就是说上面说的"技术上可以实现,但不推荐"系列。而规范中说到的豁免情况也就不难理解了,每个HTTP的具体实现都规范的遵循程序都不一致,比如说早期的Flutter DIO就支持DELETE带BODY,后来DIO为了遵循HTTP规范,又取消DELETE带BODY的支持,而早期JDK也是不支持的,CURL本身应该是支持,所以如果你能直接把请求直接发送给源服务器,且该服务器此前已通过带内(in-band)或带外(out-of-band)方式明确表明此类请求具有特定目的且会得到充分支持的情况下,你就可以使用带BODY的DELETE了。

其实从http报文的角度看,他们完全都是一样的。没有任何区别。大家能发送的信息都是一样的。你能做的我也能做,不一样的在于method所代表的这个请求的语义。

结论

说到底,在http规范任何方法都能发送请求实体。他们报文时,没有任何区别的;但是在浏览器中,比如说,XMLHttpRequest就遵循规范的限制,浏览器中ajax发送的http请求GETDELETE请求不能携带实体。

相关推荐
天蓝色的鱼鱼1 小时前
扔掉 ESLint + Prettier:Biome 全家桶实战
前端
533_2 小时前
[element-plus] el-tabs和el-menu联动
前端·javascript·vue.js
小呀小叮当~2 小时前
Telegram 有哪些实用功能?一文了解
前端·人工智能·后端·其它
索西引擎2 小时前
【React】React Fiber 架构:设计动机、核心机制与调度策略分析
前端·react.js·架构
雨季mo浅忆2 小时前
上传文件夹
前端·vue3
谙忆10242 小时前
响应式图片实战:srcset、sizes、picture 与 art direction 到底怎么用
前端
索西引擎4 小时前
【React】JSX:JavaScript 语法扩展的本质、编译机制与表达能力分析
前端·javascript·react.js
国科安芯12 小时前
航天电子模拟前端三大支柱:精密运放、高速运放与电压监控的协同设计方法——ASL8522S/ASL622S/ASL706S技术解析
前端·单片机·嵌入式硬件·fpga开发·架构·安全性测试
神明不懂浪漫13 小时前
【第四章】CSS(二)——文本外观属性与复合选择器
前端·css·经验分享·笔记