本文的内容源自其余博客的总结,属于笔者的读书笔记,结构以下:html
首先咱们要解决的第一个问题是:GET 和 POST 是什么?git
GET 和 POST 其实都是 HTTP 的请求方法。除了这 2 个请求方法以外,HTTP 还有 HEAD 、PUT 、DELETE、TRACE、CONNECT、OPTIONS 这 6 个请求方法。因此HTTP 的请求方法共计有 8 种,它们的描述以下所示:github
表格数据来源:菜鸟教程web
接下来咱们解决第二个问题:请求方法如何使用?面试
要解决这个问题,咱们首先须要了解 HTTP 的请求报文结构:数据库
能够看到 HTTP 的请求报文由三部分构成:api
GET /search/users?q=JakeWharton HTTP/1.1 Host: api.github.com Connection: keep-alive Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3 Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9 Cookie: _octo=GH1.1.1623908978.1549006668; _ga=GA1.2.548087391.1549006688; logged_in=yes; dotcom_user=GoMarck; _gid=GA1.2.17634150.1554639136; _gat=1
咱们重点看到请求行:浏览器
GET /search/users?q=JakeWharton HTTP/1.1
能够看到请求方法用的是 GET 请求,URL为/search/users?q=JakeWharton,协议为 HTTP1.1。缓存
请求行下面部分全都是请求头部,咱们能够看到 host 为 api.github.com,链接方式为长链接等信息。值得注意的是咱们这个例子中是不存在请求数据的。安全
接下来咱们在来看一下 POST 请求的报文(该例子源自其余博客):
POST / HTTP/1.1 Host: www.wrox.com User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6) Gecko/20050225 Firefox/1.0.1 Content-Type: application/x-www-form-urlencoded Content-Length: 40 Connection: Keep-Alive name=Professional%20Ajax&publisher=Wiley
能够看到请求行中请求方法为 POST,URL 为空,协议版本也是 HTTP1.1 。它和上面 GET 方法例子不同的地方在于它的请求参数是位于请求数据中的,能够看到 name=Professional%20Ajax&publisher=Wiley 就是它的请求数据。而且咱们要注意到在请求数据和请求头之间是空出一行的,这是必不可少的。
安全性: 指的是非修改信息,即该操做用于获取信息而非修改信息。换句话说,GET 请求通常不该产生反作用,也就是说,它仅仅是获取资源信息,就像数据库查询同样,不会修改,增长数据,不会影响资源的状态。幂等性(Idempotence): 则指的是不管调用这个URL 多少次,都不会有不一样的结果的 HTTP 方法。而在实际过程当中,这个规定没有那么严格。例如在一个新闻应用中,新闻站点的头版不断更新,虽然第二次请求会返回不一样的一批新闻,该操做仍然被认为是安全的和幂等的,由于它老是返回当前的新闻。
上面说了那么多 GET 方法和 POST 方法各自的特色,它们在外在的表现上彷佛是有着诸多的不一样,可是实际上,它们的本质是同样的,并没有区别!!!
这彷佛有些难以想象,可是咱们从新回想一下 GET 和 POST 是什么?它们是 HTTP 请求协议的请求方法,而 HTTP 又是基于TCP/IP的关于数据如何在万维网中如何通讯的协议,因此 GET/POST 实际上都是 TCP 连接。
也就是说,GET 和 POST 所作的事实际上是同样的,若是你给 GET 加上请求数据,给 POST 加上 URL 参数,这在技术上是彻底可行的,事实上确实有一些人为了贪图方便在更新资源时用了GET,由于用POST必需要到FORM(表单),这样会麻烦一点(可是强烈不建议这样子作!!!)。
既然 GET 和 POST 的底层都是 TCP,那么为何 HTTP 还要特别将它们区分出来呢?
其实能够想象一下,若是咱们直接使用 TCP 进行数据的传输,那么不管是单纯获取资源的请求仍是修改服务器资源的请求在外观上看起来都是 TCP 连接,这样就很是不利于进行管理。因此在 HTTP 协议中,就会对这些不一样的请求设置不一样的类别进行管理,例如单纯获取资源的请求就规定为 GET、修改服务器资源的请求就规定为 POST,而且也对它们的请求报文的格式作出了相应的要求(例如请求参数 GET 位于 URL 而 POST 则位于请求数据中)。
固然,若是咱们想将 GET 的请求参数放置在请求数据中或者将 POST 的请求数据放置在 URL 中,这是彻底能够的,虽然这样子作并不符合 HTTP 的规范。可是这样子作是否能获得咱们指望的响应数据呢?答案是未必,这取决于服务器的行为。
以 GET 方法在请求数据中放置请求参数为例,有些服务器会将请求数据中的参数读出,在这种状况下咱们依然能得到咱们指望的响应数据;而有些服务器则会选择直接忽略,这种状况下咱们就没法获取指望的响应数据了。
因此,对于 GET 和 POST 的区别,总结来讲就是:它们的本质都是 TCP 连接,并没有区别。可是因为 HTTP 的规定以及浏览器/服务器的限制,致使它们在应用过程当中可能会有所不一样。