天天看点

对POST和GET区别的一个灵魂拷问

2020.4.21做一个更新,面试被问了这个,被问到自闭,希望大家都对面经上的东西做一个足够的了解,知其然也要知其所以然。

———这里开始是我写的原文和其他大多数面试题一样(拷问更新在最下方)———

首先我们需要了解到GET和POST是什么?

POST和GET是HTTP协议的两种请求方式,都是基于TCP/IP协议的请求方法,比如我们经常在ajax请求中使用。

GET请求

GET请求传输过来的数据是更随URL传递过来的,URL与数据以?隔开

例如:https://mp.csdn.net/mdeditor?nt_checkout=1

not_checkout=1#即为传递过来的数据

传输数据大小限制:

理论上无数据大小传输限制,但各浏览器以及微软为了安全都做了限制(如1024k等)

一般用途:

从服务器端获取数据,不会对请求数据产生影响

回退:当浏览器回退时,GET不会再次提交,GET的数据会被存在浏览器的缓存中

编码限制:GET只能URL编码(通过URL传参),接收ACSII编码

POST请求

主要以数据包的形式进行数据的传输

传输数据大小限制:

理论上无数据大小传输限制

一般用途:

向服务器传送数据,一般会对数据是进行修改操作

预请求:

POST可能会发送一次预请求(比如用来判断是否跨域),如果预请求成功服务器会返回100,接下来他会发送正式的数据包,成功会返回200

注意:仅仅是可能,在火狐浏览器下只会请求一次

安全性:POST相对GET要安全一些,GET请求只能通过序列化的传值,而POST是将数据放在request body 里,不会直接被看到

回退:当浏览器回退时,POST会再次重新去提交,其内容无法存到缓存中

还有一点:

POST与GET都可以做到对服务器上的数据进行获取、修改、添加、删除,其实两者本在传输上没有任何本质上的区别只是浏览器厂家做出的限制而已,为什么这么说因为本质都是基于传输层的TCP/IP协议,而且在http协议上也并没有做出一个相应的规定

—————————————下方为最新更新—————————————

上面都是我们经常在一些面经中看到的答案

标题接下来做个深入灵魂的提问

为什么GET请求会做缓存,而POST请求不会做一个缓存?

我:因为GET请求是一个幂等的操作,GET请求的缓存主要是强缓存和协商缓存

面试官:那GET能缓存,POST为撒不能缓存

我:…

这个网上我没有查到对应的一个标准,我个人觉得可以从幂等的方向来考虑,因为post请求是有副作用的,每次请求过来的数据是不一样的,因此get这种可以做一个缓存。

你说他支持的编码格式比较多,那他支持哪些格式呢

我:GET的参数只能支持ASCII,而POST能支持任意binary

面试官:为什么?

我:…

在网络标准中做了一个这样的规定:

“只有字母和数字[0-9a-zA-Z]、一些特殊符号”$-_.+!*’(),"[不包括双引号]、以及某些保留字,才可以不经过编码直接用于URL。"

对于url的详细解释可以看阮一峰老师的文章

也就是说其他字符都说经过编码后才在url上显示的,这就是为什么说url只支持ACSII字符的原因

为什么说POST更加安全,而GET不更加安全?

我:啊!因为get请求是URL传输,所以容易看到,POST请求是在request的body体里,抓包才能看到!

面试官:那你这个URL是指的哪个URL?浏览器上方那个?

我:就是在控制台历NetWork中看到的传值

面试官:那我现在明确告诉你,在控制台传递的值我们都可以看到

我:…(其实这里的url是指请求接口的url,我不知道当时咋想的,其实他想考我http协议,天)

我们来看在chrome控制台Network项对请求的一个监控

对POST和GET区别的一个灵魂拷问

上面分别是一个get和post请求,并且分别传值操作,我们可以看到后面的值确实都可以看到。

从协议的角度来看,http协议是一个明文协议,每个HTTP请求和返回的每个byte都会在网络上明文传播,不管是url,header还是body。因此这完全不是能否看到的问题。

接下来你可能又会产生疑问,那这个安全肯定不是凭白无故产生的把,ok那我们看看在网络传输里POST请求里的body里的请求是怎么样的

先看GET的抓包

对POST和GET区别的一个灵魂拷问

在看看POST抓包

对POST和GET区别的一个灵魂拷问
对POST和GET区别的一个灵魂拷问

下面这里就是request body中的数据

发现确实在http数据报上POST请求确实是被规定封装在body的体内的,你要是硬说他安全也不是不行,但请你一定讲清楚理由

你在说说预请求

对POST和GET区别的一个灵魂拷问

像上图就是属于一个简单请求,一次请求一次返回不会有预请求,预请求就会多出一个报文,方法为options

预请求可以看看这篇文章

参考文章:

https://www.zhihu.com/question/28586791

http://www.ruanyifeng.com/blog/2010/02/url_encoding.html

继续阅读