[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 的規定以及瀏覽器/服務器的限制,致使它們在應用過程當中可能會有所不一樣。

相關文章
相關標籤/搜索