前言
前段时间在开发公司的积分商城,前期都没啥问题,一切都很顺利,到了跟前端联调的时候,尴尬了,吵起来了,搞得我很不爽,具体原因如下:
大致原因是:他说
get
请求携带body他那里处理不了,我就很奇怪了,为什么试配不了,当时很无语,一口咬定就觉得是他的问题,因为我所有的接口都测试过的,用Postman请求过都是可以的,他给的理由是前端封装了,是这样封装的,没办法,当时我只能满怀怨气的改了,贼鸡儿不爽,因为他没给我一个合适的理由,哈哈
自己说服自己
跟他聊完之后,想了很久,总觉得不对,我们公司也不小,是个上市公司,里面大佬还是有的,所以我觉得这样封装肯定是有理由的,主要是想给自己一个理由,不然想不通为啥前端要这样封装,为什么不能做这样的请求!前端说的因为公司这样封装了一套,很明显是错的,他自己也不清楚为什么,就是公司这样规定,所以他遵守了,也这样做了…
然后就开始找资料,看了一些博客,说:
HTTP协议定义的报文是支持GET请求携带body的,所以这个问题不是HTTP协议限制的;使用postman可以传递携带body的GET请求到Spring的web server,所以也不是web server/tomcat限制的;最后,根据逻辑链路排除法,得出的结论是浏览器引擎不支持GET请求携带body。
说了感觉没说,没任何依据,不足以说服人
1、然后:
后来自己去查看了Http协议,结果发现惊喜,里面有一段是这样写的:
A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.
http规范明确说了get请求携带body属于未定义行为,至于未定义行为有什么后果,那就是各家的实现可以有天壤之别,想怎么实现都可以,所以浏览器最好的做法就是禁止发送带有payload的get请求,因为你根本不知道这个请求在网络上传输时会被解释成什么样子。至于postman之类的工具,我猜可能是因为它本身就是用于调试http请求的,所以支持payload无可厚非。至于某些服务器支持这种语义,也不代表网络上所有设备都支持,所以 GET 不能携带 body 是事实上的标准。
2、继续
其实很多人都强调一点:GET请求不应携带请求体,服务器应忽略(或者说丢弃)GET请求的请求体,依据也能在协议中找到:
[RFC2616] A server SHOULD read and forward a message-body on any request; if the request method does not include defined semantics for an entity-body, then the message-body SHOULD be ignored when handling the request.
[RFC2616] A message-body MUST NOT be included in a request if the specification of the request method does not allow sending an entity-body in requests.
但为什么还是有人这样用呢,甚至开发很久的程序员,也没意识到这个问题,难道是用的人多了?错的也是对的?不过即使这样,也不是这样使用的一个理由!
当然,包括我在内
当然还有一个原因:在后续的http协议中,RFC2616已经过时,把SHOULD
应该也去了,要求更加宽松
[RFC7230] Request message framing is independent of method semantics, even if the method does not define any use for a message body.
但错的就是错的
规范地址: datatracker.ietf.org
GET | POST | PUT | DELETE | |
---|---|---|---|---|
请求是否有主体 | 否 | 是 | 是 | 可以有 |
成功的响应是否有主体 | 是 | 是 | 否 | 可以有 |
安全 | 是 | 否 | 否 | 否 |
幂等 | 是 | 否 | 是 | 是 |
可缓存 | 是 | 否 | 否 | 否 |
HTML表单是否支持 | 是 | 是 | 否 | 否 |
后续
后来我跟同事说了这个问题,他立即反驳我说:
但凡你用过es都不会这样说了
看下es的查询接口,是不是GET+body
然后继续查资料:
查了下,ES确实支持用GET+body查询,但文档也说了,并不是所有客户端都支持GET+body,所以查询也同时支持了POST。
虽然对ES了解不深,但我的感觉是ES主要是当作一个数据库来使用的,针对ES的查询也基本是由后端去发起的,因此对客户端的能力(GET能否携带body)是能够提前知道的,而针对web开发的大部分场景并不是这样的,api的作者并不知道客户端的能力,要求必须要使用支持GET+body的请求库才能使用这个接口也是不合理的,因此针对web的api不应该使用GET+body的方式并没有什么问题。
总结来说就是,ES是在特定场景重新去定义了GET+body的语义,而针对通用的web API作者并不适合。
ES对get请求携带body说明:www.elastic.co
结束语
任何原因都不要主观下结论,事实依据很重要文章来源:https://www.toymoban.com/news/detail-400760.html
事实证明,我是菜逼!!文章来源地址https://www.toymoban.com/news/detail-400760.html
到了这里,关于和前端吵架的一天的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!