本文的內容源自其餘博客的總結,屬於筆者的讀書筆記,結構以下: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 的規定以及瀏覽器/服務器的限制,致使它們在應用過程當中可能會有所不一樣。