千家信息网

在GET请求中使用body的实例分析

发表于:2024-11-26 作者:千家信息网编辑
千家信息网最后更新 2024年11月26日,在GET请求中使用body的实例分析,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。故事还得从一个bug说起。今天有人问我
千家信息网最后更新 2024年11月26日在GET请求中使用body的实例分析

在GET请求中使用body的实例分析,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

故事还得从一个bug说起。今天有人问我,为什么发到后端的请求400了,我说肯定是参数不对,你去检查检查GET、POST之类的方法写没写对,要么就是字段没对上,无非是这几个问题。然后他说检查过了,没问题啊;我不太相信,但是看了看前端发送的请求,好像确实没啥问题:

我说既然这样,那肯定是后端写错了,但后端说他已经用postman测过了,肯定没问题。这就很有意思了。于是我要来了后端的代码:
不出所料,后端把GET请求里的参数当成body的内容了,把@RequestBody改成@RequestParam应该就没问题了;改完之后果然好了。

这本来是一个很简单的问题,没什么可说的,但是他们接着问我,为什么GET请求里不能用body?我寻思着平时也没什么人在GET请求里加body吧,而且一直以来都听说这么用不好。但是为什么不好呢?所以我就查了一些资料,最后干脆又去RFC翻了翻。看到官方是这么说的:

[RFC7231] 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.

意思是你往GET请求里加body是不符合规范的,不保证所有的实现都支持(主要是以前的实现,因为以前曾经有相应的规定),要是出了啥问题别怪我没提醒你。而且据说老版本的postman是不支持在GET请求里加body的,也是最近才加上的支持;所以要放在以前也就没这些问题了,以前的postman根本发不了带body的GET请求。

但是这一条并不是强制规定。我看很多人都强调一点,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.

当然,官方也只是说SHOULD,没有像前文一样措辞严厉地强调类似HEAD这种的请求MUST NOT have a message body:

[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.

但是很可惜的是,RFC2616已经过时了。现在的说法变成了这样,连SHOULD都直接去掉了,要求更加宽松:

[RFC7230] Request message framing is independent of method semantics, even if the method does not define any use for a message body.

难道是因为错的人多了,错的也变成了对的?不过即使是这样,也并不是在GET请求里加上body的理由。

这个问题算是解决了。但是我看到网上各路大神说到GET加body的时候,还提到一个,就是往GET里加body会导致缓存机制失效。"GET 被设计来用 URI 来识别资源,如果让它的请求体中携带数据,那么通常的缓存服务便失效了,URI 不能作为缓存的 Key。"我一开始以为是在服务器上配置的缓存,比如Nginx的cache之类的机制,后来发现好像并非如此。这个缓存,大概是指那种预加载和后存储,会涉及到一个网络请求的"安全性"。如果不安全,显然是不能缓存的。

那么,GET和POST的区别和应用?这问题挺复杂。简而言之,就是"安全"和"不安全"的区别。什么是安全?不用承担责任。什么是不安全?可能需要承担责任。举个例子,点击某个链接以同意某个协议,这个请求明显就是不安全的,因为需要承担责任。如果采用GET,就违反了GET应该用于安全请求的规范。因为浏览器可能在你不知情的情况下预加载这个页面(因为是"安全"的GET请求),这样相当于你在不知情的情况下同意了某个协议,这显然是我们不希望看到的。在契约式的设计里,违反契约的行为是会带来严重的后果的。浏览器按照契约预加载了安全的GET请求,但这本身是不安全的,带来的后果自然要由打破契约的人承担(将这个请求设计成GET的人出来挨打)。

之所以强调"安全",而不是按照常规的说法强调副作用,因为有副作用的请求不代表不安全;举例来说,服务器有一个显示访问人数的功能,这个功能就可以用GET来做。虽然每次访问都会发送改变服务器状态(计数器)的请求,但用户不会因为这个请求承担责任,这个请求是安全的。至于什么GET请求的URL有长度限制(后来事实证明其实没有),什么GET请求的URL里不能有中文(或者说非ASCII吧),都只是实现上的区别;从最初的设计上来说区别并不在这里。

当然,这些都是纯粹的理论层面的东西。如果遵守RESTful的规范,采用语义化的GET/POST请求,自然也就不会有这些问题了。因为通常来说,查询是安全的;这也是GET的主要作用。

说起来也挺有意思的,学习了这么久,经常提起RFC,也没搞清楚RFC究竟是个啥玩意,这次就一并查了。虽然我总觉得这是受到6f名词解释的影响……原来是叫"Request For Comments"。

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注行业资讯频道,感谢您对的支持。

安全 问题 缓存 里加 服务 契约 就是 服务器 责任 支持 设计 检查 肯定 有意思 没什么 不好 内容 副作用 功能 参数 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 株洲软件开发找谁 服务器安全限制怎么关闭 延长石油网络安全 服务器查看安全策略 江苏电商软件开发价钱是多少 服务器停服和关服的区别 腾讯会议代理服务器上网无法登陆 上海通用软件开发市场价 家里架设服务器有用吗 网络安全渗透测试理论选择题题库 上海普瓦互联网科技有限公司 通信网络安全知识竞赛题库 软件开发发展历史 网络安全法与电信法 南桥坏了可以进入网络安全模式吗 通信网络技术专业知识 渭南网络技术价目表 互联网科技金融公司 数据库有外键叫什么 eve服务器每天多久维护 租服务器做网站 光与夜之恋如何查看服务器 服务器获取设备名称 虹口区创新数据库服务商销售 邯郸web前端软件开发哪里好 九折型材服务器机柜 通信工程与网络安全专业区别 牟平区定制软件开发哪家靠谱 数据库有外键叫什么 中小学网络安全知识答题
0