get请求可以传body吗_GET 和 POST 的区别?

同样还是面试被问到的问题,经过这两天的复盘,发现之前对其的了解只是冰山一角,这两天也学到了不少新的知识,不得不说面试的确能帮我们弥补一些不足。本文将从基本概念、两者之间的区别以及几个常见问题来进行介绍,首先我们先来明确几个概念

基本概念

HTTP定义了与服务器进行交互的不同方法,常见的有四种:GETPOSTPUTDELETE。其中,GETPOST最常用。

GET用来获取资源,它只是获取、查询数据,不会修改服务器的数据,从这点来讲,它是安全的(后面还会从另一方面分析它的不安全性)。由于它是读取的,因此可以对GET请求的数据进行缓存。

POST则是可以向服务器发送修改请求,进行数据的修改的。举个例子:比如说我们要在知乎、或者论坛下面评论,这个时候就需要用到POST请求。但是它不能缓存,为什么呢?设想如果我们将“评论成功”的页面缓存在本地,那么当我发送一个请求的时候,直接返回本地的“评论成功”页面,而服务器端则什么也没有做,根本没有进行评论的更新,岂不是难以想象。

区别

我们常说的一些区别都是一些表面上的,比如:GET没有POST安全、GET请求时URL的长度是有限制的、GET没有bodyPOSTbody等等。这些都是针对浏览器中的要求, 在使用HTTP作为接口进行传输时,就没有这么多条条框框了,此时GETPOST只是HTTP协议中的两种请求方式,而HTTP协议是基于TCP/IP的应用层协议, 无论GET还是POST,用的都是同一个传输层协议,所以在传输上没有区别。

因此,在用作为接口进行传输时,最大的不同就在于报文格式上的不同了

POST /url HTTP/1.1 rn
GET /url HTTP/1.1 rn

上面所示的分别为POST方法请求的报文第一行和GET请求的报文第一行, 显而易见的区别就是方法名不同。除此以外,就没有那么多要求了,GET也可以有bodyPOST也不一定非要使用body,只要客户端和服务器端确定好规范即可,至于形式则你们随意。只不过现在已经习惯了现有的规则,再去改变有些麻烦,毕竟客户端和服务器端要花时间去探讨具体的对接形式。

由于平时大部分见到的都是基于浏览器的请求,下面我们再看几个常见的问题

  1. 我们前面说,无论是GET请求还是POST请求,其本质都是不安全的,为什么这样说呢?如果仅仅从GET请求的参数在地址栏是可见的,POST是不可见的,那就太肤浅了。 由于HTTP自己本身是一个明文协议,每个HTTP请求和返回的数据在网络上都是明文传播,无论是urlheader还是body。 只要在网络节点捉包,就能获取完整的数据报文,要防止泄密的唯一手段就是使用HTTPS(用SSL协议协商出的密钥加密明文HTTP数据)。
  2. 为什么在浏览器中GET请求方式的url长度有限制呢?这是因为浏览器要对url进行解析,而解析的时候就要分配内存。对于一个字节流的解析,必须分配buffer来保存所有要存储的数据。而url这种东西必须当作一个整体看待,无法一块一块处理,于是就处理一个请求时必须分配一整块足够大的内存。如果url太长,而并发又很高,就容易挤爆服务器的内存。
  3. POST是发送两个请求吗? 上面提到POST请求可以被分为“请求头”和“请求体”两个部分,那这两部分是一起发送出去呢?还是先发“请求头”,再发“请求体”呢? 在HTTP协议中并没有明确说明POST会产生两个数据包。之所以会发两个数据包,则是出于以下考虑:如果服务器先收到“请求头”,则会对其进行校验,如果校验通过,则回复客户端“100 - Continue”,客户端再把”请求体“发给服务器。如果请求被拒了,服务器就回复个400之类的错误,这个交互就终止了。这样做的优点是可以避免浪费带宽传输请求体,但是代价就是会多一次Round Trip。如果刚好请求体的数据也不多,那么一次性全部发给服务器可能反而更好。所以说,这和POST完全没有关系,只是基于两端的一种优化手段罢了。
上一篇:自然语言处理之关键词提取TF-IDF


下一篇:Spring小知识2