前端求生之路HTTP

114 阅读4分钟

最近忙着加班学习 ,等哪天把学习笔记分享一下。

根据 w3schools 网上的文章讲解:

引言

  • GET请求在浏览器回退时候是无害的,而POST请求会再一次提交请求的。
  • GET请求产生的URL地址可以被Bookmark(书签),而POST不可以。
  • GET请求会被浏览器主动缓存,而POST请求不会,除非手动设置。
  • GET请求只能进行URL编码,而POST支持多种编码方式。
  • GET请求参数会被完整的保留在浏览器历史记录里,而POST请求中的参数不会被保留。
  • GET请求在URL中传送的参数是有长度限制的,而POST请求的长度限制要远大于GET请求的参数长度。
  • 对参数的数据类型,GET请求只接受字符串类型,而POST请求没有限制。
  • GET请求比POST请求更不安全,因为参数暴露在URL上,不能用来传递敏感信息。
  • GET请求参数通过URL传递,POST请求参数放在Request body中。

但是,实际上GET请求和POST请求本质上是没有区别的。GET请求和POST请求是HTTP协议中的两种发送请求的方法。而HTTP是基于TCP/IP的关于数据在万维网中通信的协议。

HTTP的底层是TCP/IP。所以GET请求和POST请求的底层也是TCP/IP,即GET/POST都是TCP链接,GET和POST请求能做的事情是一样的。在理论上来说,可以给GET请求加上Request body,给POST请求带上URL参数。

那么,回到这个问题上,GET请求和POST请求的区别是什么?

GET和POST区别

在万维网中,TCP就像是汽车,我们用TCP来运输数据,但是如果道路上都是一摸一样的汽车,那么这个路线看起来是一片混乱,送急件的汽车可能为前面装载货物的汽车拦堵在路上,整个交通系统一定会瘫痪的。

为了避免这种情况的发生,交通规则HTTP诞生了,HTTP给汽车运输设定了几种服务类型,例如GET、POST、PUT、DELETE、PATCH、OPTION等,HTTP规定,当执行GET请求的时候要给汽车贴上GET标签(设置method为GET),并且要求把传送的数据放到车顶(URL)上以方便记录,如果是POST请求,就要在车上贴上POST标签(设置method为POST),并把货物放到车厢(Request body)中。虽然我们可以在GET请求的时候往车厢里偷偷藏点货物,或是在POST请求的时候,在车顶放一些数据。HTTP只是一个行为准则,而TCP才是GET和POST的实现基本。

那么,为什么会有对参数的大小限制呢?

在万维网这个交通网络中,除了车辆,还有运输公司。不同的浏览器(发送HTTP请求)和服务器(接收HTTP请求)就是不同的运输公司。

虽然我们我们可以在车辆上装了无限的货物,但是运输公司对于装货和卸货也是要很大成本的。他们会限制单词运输量来控制风险,数据量过大对浏览器和服务器都是很大负担。大部分浏览器会限制URL长度在2K个字符,而服务器大部分最多处理 64K大小的URL。超出的部分是不会处理的。如果我们在GET请求中在request body藏了数据,不同的服务器处理的方式是不同的,有些会卸货读取数据,有些服务器直接就会忽略,所以,不建议GET请求的Request body中放数据。

所以,从这个角度来说:GET请求和POST请求本质都是TCP链接,并无差异,但是由于HTTP的规定和浏览器、服务器的限制,导致他们在应用过程里体现出不同。

除此以外,他们还有一个重大的区别:GET请求会产生一个TCP数据包,POST请求会产生两个TCP数据包。

对于GET请求,浏览器会把header和data一并发送出去,服务器响应200,返回数据。

对于POST请求,浏览器会先发送header,服务器响应100,浏览器再发送data,服务器响应200,返回数据。

换句话来,GET请求只需要汽车跑一趟就把货物送到了,POST请求需要跑两趟,第一趟过来先和服务器打一声招呼,“嗨,我等下要送一批货物过来,你们打开门迎接我一下”,然后再回头把货物送过去。

最后,为什么不能通过GET请求来替代POST请求? GET请求与POST请求都有自己的语义,不能混用。 在网络环境良好的情况下,发一次包的时间和发两次包的时间差别基本可以忽略不计,而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。 并不是所有浏览器的POST请求会发送两次包,Firefox就只发送一次。