生产问题:出现重复创建数据漏洞,架构师级别的排查思路(下)Get请求和Post请求到底有什么区别?该怎么用?

3 篇文章 0 订阅
1 篇文章 0 订阅

生产问题:出现重复创建数据漏洞,架构师级别的排查思路(下)Get请求和Post请求到底有什么区别?该怎么用?

Get请求和Post请求,到底有什么区别?

这是一个前几年非常高频的面试题,随着大家整体水平的提高,这道题逐渐淡出了。但是,在我实际接触到的人里面,能真正认识到其中区别的人并不多。那么,在Restful风格接口普及的今天,好好认识HTTP的每一个Method就更有必要了。

所以,本文,就来分析分析,HTTP的Method的区别(包括但不限于Get,Post),以及它们都有哪些坑。

Get和Post的区别,我们能百度到的很多回答没讲到核心内容

  1. 安全:Get不安全,Post安全。这个说法来自于Get请求的参数会被直接携带在URL里,Post请求的参数是放在Body里的,而URL就不安全。这一点,在曾经还有点道理。因为以前,很多请求发起就是由浏览器携带参数,跳转到后台,然后后台再重定向到渲染好资源的页面资源。但是现在,前后端分离,基本上跳转都已经不存在了。Get请求和Post请求,都是异步发起,然后动态更新资源,不存在Get请求会暴露参数的问题了。所以安全这个说法,放在如今,实在是太勉强了。
  2. 参数长度:Get参数长度更短,如果要传数据比较大的参数需要通过Post。Get参数长度的限制确实比较有限,但也并不是它们的核心区别。Get就算参数再有限,对于90%的请求传参都是够用的。那为什么还有那么多请求是用Post发送的呢?所以说,这个说法,也有点勉强。
  3. 缓存:Get资源会被缓存,而Post资源不会。这个算区别,但不是本质区别。因为其实现在的前端技术,POST请求如果有数据返回,也可以进行缓存。

那么,区别到底在哪呢???

其实,在底层实现上没有任何区别。Get和Post都是通过TCP/IP连接。只要你想的话,甚至可以Get用Body传参,Post用URL传参,在技术上,都是可以实现的。

先别急着打我,接下来就要说它们真正的区别了。

Get和Post 真正的区别

既然技术上Get和Post没有区别,那他们的区别在哪里呢?其实真正的区别就在于——语义。那些种种区别,其实都是语义带来的。

学生:老师!HTTP的GET和POST请求到底什么区别呀?

老师:还记得你让人传话你小跟班帮你买早餐,结果买多了的那事吗?

学生:当然记得!一提这我就来气。

学生:当时我喊小胖帮我传话给我小弟带份饭给我,我看他趴桌子上一动不动,以为他在睡觉。我抄完卷子看他睡醒了,又喊他传话我小弟帮我带饭。谁知道,他之前就已经给我小弟传过话了,这次他以为我想吃两份,又传了一次。小弟也是个憨憨,居然真就买了两份回来。

老师:为什么会出现这种情况呢?就是因为小胖对你要带话的行为没有正确的理解,你喊一次他就做一次。

学生:是啊,那次之后我就交代小胖了,以后我喊多次也只帮我处理一次就好了。

老师:然后呢?就发生了你交白卷的操作是么?

学生:老师,您就别揭我伤疤了!

学生:那次考试,我一道题都不会写,我让小胖帮我找我小弟给我写份答案。结果写的太潦草,我一个字都不认识。没办法啊,我就让小胖再重新去帮我要一份。

学生:结果呢?结果到收卷子的时候,也没等到传来下一份答案。问他原因,他居然说是我教的“只处理一次就好了”,我真是气不打一处来。

老师:你们这就是没有共识的结果,没有对传话的内容做合理的约定。你们的约定啊,应该是:如果涉及花钱的传话,就不要多次传。如果是要答案这种事情,不用花你的钱的话,那就可以多次传递。

老师:GET和POST也是这个区别。在HTTP协议中,这两个 Method 在使用过程中几乎没有区别。POST能做的,GET都能做,反过来也一样。核心区别在哪呢?

老师:没错,就是语义!在网络世界中,路由器、交换机、网管、拦截器、负载均衡、CDN、缓存有若干的网络组件与网络插件。它们如何判断你到底想干啥呢?没错,就是HTTP Method,也就是GET和POST(当然还有PUT,DELETE等)。

老师:所有的网络元件,大家定义一个共识。GET请求就是用来查询数据的,因为你是查询数据,不会带来负面影响,所以就可以允许自动重发,可以被缓存等。

老师:但是,反过来你想一下。POST请求有部分类似于转账请求。可以被重发么?

学生:那当然不行,转账请求如果被重发了,我本来想给老师发5¥红包,但是万一网络一抖动,闹不好我这个月生活费就没了!

老师:对,诸多网络组件也是这么约定的。它们一看,啊,你这是个POST请求,一定是个不希望重发的请求,就算抓发的时候没收到响应,也不会帮你多次转发啦。

学生:难怪转账没有发生过重复转账的行为,原来是这样啊!

老师:嗯哼~

image-20221208210013358

其实,Get和Post的区别,也在这里。这是一种HTTP协议的一种约定。在语义上把它们区分开(实际上不仅限于GET和POST):

  • GET - 从指定的资源请求数据。
  • POST - 向指定的资源提交要被处理的数据。

至于那些细节的特性,全都是基于这些最基本的语义。比如缓存,GET被认为是请求资源,所以可以被缓存。而POST被认为是提交数据,所以不可以被缓存。重发也一样,GET是请求资源,所以很多网络转发的中间件会对其自动重发。而POST是提交数据,所以一般不会重发。

这些语义特性不是强制的。如果,你自己写的网络中间件,为了防止重发带来的问题,你也可以选择对于所有请求一视同仁。只不过,这不符合规范,不推荐这么做而已。

拓展

其实类似的场景还有很多。比如在Java技术栈中,get方法用于获取属性,set方法用于设置属性。甚至,诸多框架就针对Getter,Setter方法做了增强,并要求对象的类,必须要有Getter,Setter方法。你如果硬要问“我的Getter方法用来做其他的事行不行?”。我只能说,不是不可以这么用,只是这样用不符合规范,会有很多麻烦。就像HTTP的GET请求会被重发一样,很多工具和框架对于Getter和Setter的很多增强处理,可能会因为你违反了通常的Getter的规范,而出现反直觉的结果。所以,尽可能还是避免这样的操作。

感谢能阅读到这里的你!

希望本文对你可以有帮助,存在的漏洞以及待完善的地方也欢迎指出!

期待你的点赞,收藏,以及关注!你的支持,是我继续更新的最大动力!

最后,也欢迎你关注我的公众号【猿树洞】,将不定期为大家带来问题解答以及心得分享。(嗯。。。。。非常不定期。。。)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值