[Java网络安全系列面试题] GET 和 POST 的区别在哪里?

[Java网络安全系列面试题] GET 和 POST 的区别在哪里?

 

一. 概述

本文的内容源自其余博客的总结,属于笔者的读书笔记,结构以下:html

  • HTTP 的请求报文
  • GET 方法的特色
  • POST 方法的特色
  • GET 和 POST 的区别

二. HTTP 的请求报文

首先咱们要解决的第一个问题是:GET 和 POST 是什么?git

GET 和 POST 其实都是 HTTP 的请求方法。除了这 2 个请求方法以外,HTTP 还有 HEAD 、PUT 、DELETE、TRACE、CONNECT、OPTIONS 这 6 个请求方法。因此HTTP 的请求方法共计有 8 种,它们的描述以下所示:github

表格数据来源:菜鸟教程web

[Java网络安全系列面试题] GET 和 POST 的区别在哪里?

 

接下来咱们解决第二个问题:请求方法如何使用?面试

要解决这个问题,咱们首先须要了解 HTTP 的请求报文结构:数据库

[Java网络安全系列面试题] GET 和 POST 的区别在哪里?

 

能够看到 HTTP 的请求报文由三部分构成:api

  • 请求行:由请求方法(Method)、URL 字段和 HTTP 的协议版本组成,注意其中的空格、回车符和换行符均不可省略,因此咱们的请求方法实际上就是位于请求行中的了。
  • 请求头部:位于请求行以后,个数能够为 0~若干个,每一个请求头部都包含一个头部字段名和一个值,它们之间用冒号 ":" 分隔,在最后用回车符和换行符表示结束。
  • 请求数据:若是请求方法为 GET,那么请求数据为空。它主要是在 POST 中进行使用,适用于须要填表单(FORM)的场景。咱们经过一个实际的例子来看看 HTTP 的 GET 请求报文是什么样的,咱们这里以访问 https://api.github.com/search/users?q=JakeWharton 为例,经过抓包咱们获得的请求报文以下所示:
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 方法的特色

  1. 前面的例子:https://api.github.com/search/users?q=JakeWharton 就是一个很是典型的 **GET **请求的表现形式,即请求的数据会附在 URL 以后(放在请求行中),以 ? 分割 URL 和传输数据,多个参数用 & 链接。
  2. 除此以外,根据 HTTP 规范,GET 用于信息获取,并且应该是安全和幂等的 。

安全性: 指的是非修改信息,即该操做用于获取信息而非修改信息。换句话说,GET 请求通常不该产生反作用,也就是说,它仅仅是获取资源信息,就像数据库查询同样,不会修改,增长数据,不会影响资源的状态。幂等性(Idempotence): 则指的是不管调用这个URL 多少次,都不会有不一样的结果的 HTTP 方法。而在实际过程当中,这个规定没有那么严格。例如在一个新闻应用中,新闻站点的头版不断更新,虽然第二次请求会返回不一样的一批新闻,该操做仍然被认为是安全的和幂等的,由于它老是返回当前的新闻。

  1. GET 是会被浏览器主动缓存的,若是下一次传输的数据相同,那么就会返回缓存中的内容,以求更快地展现数据。
  2. GET 方法的 URL 通常都具备长度限制,可是须要注意的是 HTTP 协议中并未规定 GET 请求的长度。 这个长度限制主要是由浏览器和 Web 服务器所决定的,而且各个浏览器对长度的限制也各不相同 。
  3. GET 方法只产生一个 TCP 数据包,浏览器会把请求头和请求数据一并发送出去,服务器响应 200 ok(返回数据)。

四. POST 方法的特色

  1. 根据 HTTP 规范,POST 表示可能修改变服务器上的资源的请求。例如咱们在刷知乎的时候对某篇文章进行点赞,就是提交的 POST 请求,由于它改变了服务器中的数据(该篇文章的点赞数)。
  2. POST 方法由于有可能修改服务器上的资源,因此它是不符合安全和幂等性的。
  3. 从前面关于 POST 的请求报文也能够看出,POST 是将请求信息放置在请求数据中的,这也是 POST 和 GET 的一点不那么重要的区别。有一些博客的说法是 GET 请求的请求信息是放置在 URL 的而 POST 是放置在请求数据中的因此 POST 比 GET 更安全。其实这种说法颇有问题,随便抓下包 POST 中的请求报文就暴露无疑了,这又何来安全之说?
  4. 由于 POST 方法的请求信息是放置在请求数据中的,因此它的请求信息是没有长度限制的。
  5. POST 方法会产生两个 TCP 数据包,浏览器会先将请求头发送给服务器,待服务器响应100 continue,浏览器再发送请求数据,服务器响应200 ok(返回数据)。这么看起来 GET 请求的传输会比 POST 快上一些(由于GET 方法只发送一个 TCP 数据包),可是实际上在网络良好的状况下它们的传输速度基本相同。

五. GET 和 POST 的区别

上面说了那么多 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 的规定以及浏览器/服务器的限制,致使它们在应用过程当中可能会有所不一样。

相关文章
相关标签/搜索