你真的瞭解 GET 和 POST 嗎,它們的區別是什麼?

引言

本文從如下幾個方面走進 GET 與 POST 的區別:前端

  • w3school 給出的標準答案
  • 從 HTTP 是什麼開始,深刻 GET 與 POST 請求方法,即二者的本質區別
  • 常見的 GET 與 POST 誤解
    • POST 方法比 GET 方法安全?
    • POST 方法會產生兩個 TCP 數據包?

標準答案

GET 與 POST 是 HTTP 請求中最經常使用的兩種方法,GET 與 POST 的區別也是老生常談的問題了,信手拈來git

GET POST
後退按鈕/刷新 無害 數據會被從新提交(瀏覽器應該告知用戶數據會被從新提交)。
書籤 可收藏爲書籤 不可收藏爲書籤
緩存 能被緩存 不能緩存
編碼類型 application/x-www-form-urlencoded application/x-www-form-urlencoded 或 multipart/form-data。爲二進制數據使用多重編碼。
歷史 參數保留在瀏覽器歷史中。 參數不會保存在瀏覽器歷史中。
對數據長度的限制 是的。當發送數據時,GET 方法向 URL 添加數據;URL 的長度是受限制的(URL 的最大長度是 2048 個字符)。 無限制。
對數據類型的限制 只容許 ASCII 字符。 沒有限制。也容許二進制數據。
安全性 與 POST 相比,GET 的安全性較差,由於所發送的數據是 URL 的一部分。在發送密碼或其餘敏感信息時毫不要使用 GET ! POST 比 GET 更安全,由於參數不會被保存在瀏覽器歷史或 web 服務器日誌中。
可見性 數據在 URL 中對全部人都是可見的。 數據不會顯示在 URL 中。

上面是 w3school 給出的標準答案github

但你真的理解它嗎?在咱們學習了那麼多 HTTP 知識後,僅僅回答這些就夠了嗎?GET 與 POST 都是 HTTP 的請求方法,如何理解請求方法?本質區別又是什麼?web

下面讓咱們一步步走進 GET 與 POST 方法,以及二者的本質區別面試

深刻 GET 與 POST 請求方法

1. HTTP 是什麼?

HTTP (HyperText Transfer Protocol)是創建在 TCP 上的應用層協議,超文本傳輸協議。其中:算法

  • 超文本:圖片、音頻、視頻、甚至是壓縮包等
  • 傳輸:兩點之間數據的雙向傳送
  • 協議:一種行爲約定和規範

因此,HTTP 協議用更通俗易懂的話描述就是 一個在計算機世界裏專門在兩點之間傳輸文字、圖片、音頻、視頻等超文本數據的約定和規範跨域

雖然說 HTTP 協議是「傳輸協議」,但它不關心尋址、路由、數據完整性等傳輸細節,這些底層的具體傳輸工做是由 TCP/IP 協議負責,例如 IP 協議實現尋址和路由、TCP 協議實現可靠數據傳輸,另外還有 DNS 協議實現域名查找、SSL/TLS 協議實現安全通訊等瀏覽器

那 HTTP 協議主要幹嗎喃?緩存

2. HTTP 報文

HTTP 協議的核心部分就是它定義的傳輸報文的格式,例如報文的組成、解析規則等,以便於在 TCP/IP 上實現更多樣靈活的功能,如緩存控制、數據編碼、內容協議等安全

HTTP 報文分爲四部分:

  • 起始行:在請求報文中是請求行,在響應報文中是狀態行(表示服務器的響應狀態)
  • 頭部:header
  • 空行:在 header 與 body 之間實際上是有個 「空行」 的
  • 實體:咱們一般說的 body

注意:此報文中最後是一個空白行結束,沒有 body(GET 請求通常都沒有 body)

其中,請求方法就規定在起始行中:

  • 請求行:GET /uri HTTP/1.1,包含請求方法 GET 或 POST 等

  • 狀態行:HTTP/1.1 200 OK,僅僅包含服務器的響應狀態,不包含請求方法

請求方法

客戶端發起 HTTP 請求,服務器響應客戶端請求,客戶端能夠對服務器端的資源進行操做,例如查詢、添加、刪除等,但具體執行哪一種操做喃?

這就是請求方法存在的意義,它規定了客戶端的某種操做指令,用來告訴服務器端我須要進行哪一種操做,常見的請求方法有:

  • GET :獲取資源,經常使用於讀取或下載資源
  • HEAD :請求一個與 GET 請求的響應相同的響應,只返回請求頭,沒有響應體,多數由 JavaScript 發起
  • POST :用於將實體(body)提交到指定的資源,一般致使狀態或服務器上的反作用的更改
  • PUT :用請求有效載荷替換目標資源的全部當前表示。
  • DELETE :刪除指定的資源。
  • CONNECT :創建一個到由目標資源標識的服務器的隧道,多用於 HTTPS 和 WebSocket 。
  • OPTIONS :預檢,用於描述目標資源的通訊選項。經過該請求來知道服務端是否容許跨域請求。
  • TRACE :沿着到目標資源的路徑執行一個消息環回測試,多數線上服務都不支持
  • PATCH :用於對資源應用部分修改。

GET 請求方法應該是 HTTP 全部請求方法中最開始出現的了,它表示從服務器獲取資源

POST 請求方法是 HTTP 全部協議中除 GET 以外最常使用的請求方法了,它表示向指定的服務器資源提交數據,提交數據存放在 HTTP 報文中的 body 中,一般致使狀態或服務器上的反作用的更改

3. GET 與 POST 請求方法的本質區別

綜上所述,總結一下,GET 與 POST 的本質區別有兩點:

  • 請求行不一樣:
    • GET:GET /uri HTTP/1.1
    • POST:POST /uri HTTP/1.1
  • 對服務器資源的操做不一樣:
    • GET:表示從服務器獲取資源
    • POST:向指定的服務器資源提交數據(一般致使狀態或服務器上的反作用的更改)

進階:常見問題及解答

1. POST 方法比 GET 方法安全?

在 HTTP 協議裏,所謂的「安全」是指請求方法不會對服務器上的資源進行修改,「破壞」服務器上的資源

按照這種定義,GET 請求方法是安全的,它對服務器資源執行的僅僅是隻讀操做,也是冪等的

冪等指屢次執行相同的操做,結果也都是相同的,即屢次「冪」後結果「相等」

POST 請求方法是不安全的,它會修改服務器上的資源,在 RFC 裏的語義,POST 是指「新增或提交數據」,屢次提交數據會建立多個資源,因此不是冪等的

總結:

  • GET:安全,冪等
  • POST:不安全,不冪等

對於傳輸來講,GET 和 POST 報文在傳輸上都是不安全的,由於 HTTP 在網絡上是明文傳輸的,想要安全傳輸就得加密,也就是 HTTPS

2. POST 方法會產生兩個 TCP 數據包?

這個就神奇了,在部分文章中提到,POST 請求方法會將 header 和 body 分開發送,先發送 header,服務端返回 100 狀態碼再發送 body 🤔️🤔️🤔️

HTTP 協議中沒有明確說明 POST 會產生兩個 TCP 數據包,並且實際測試(Chrome、Firefox)發現,header 和 body 不會分開發送。

但爲何有些做者會這樣寫喃?我查找了相關資料,終於發現,真有這種狀況,原文在這裏:

In search of performance - how we shaved 200ms off every POST request

gocardless.com/blog/in-sea…

主要內容是做者發現 POST 比 GET 多 200ms,而後深刻研究,發現 ruby 的 net::HTTP 庫,會將一個 http 請求拆分,先發送 header 部分。另外,因爲沒有設置 TCP_NODELY ,因此第一個包以後要等待 ack ,才發下一個包,致使了一個請求有 200ms 的延遲。

另外,關於 HTTP 100  Continue:

100 Continue的目的是對HTTP客戶端應用程序有一個實體的主體部分要發送服務器,但但願在發送以前查看一下服務器是否會接受這個實體這種狀況進行優化

----《HTTP權威指南》

客戶端:

若是客戶端在向服務器發送一個實體,並願意在發送實體以前等待100 Continue響應,那麼客戶端就要發送一個攜帶了值爲100 Continue的Expect請求首部。若是客戶端沒有發送實體,就不該該發送100 Continue Expect首部,由於這樣會使服務器誤覺得客戶端要發送一個實體

服務器端:

若是服務器收到一條帶有值爲100 Continue的Expect首部的請求,它會用100 Continue響應或一條錯誤碼來進行響應。服務器永遠也不該該向沒有發送100 Continue指望的客戶端發送100 Continue狀態碼。

若是服務器在有機會發送100 Continue響應以前就收到了部分(或者所有)的實體,說明服務器已經打算繼續發送數據了,這樣服務器就不須要發送這個狀態碼了,可是服務器完成請求以後,仍是應該爲請求發送一個最終狀態碼

也就是說,沒收到客戶端的 100 Continue 就不會有響應

總結

所以,大多數框架都是儘可能在一個 TCP 包裏面把 HTTP 請求發出去的,可是也確實存在先發 HTTP 頭,而後發 body 的框架。可是具體發多少個TCP包,這個 不是 HTTP 協議的事情是操做系統 TCP 協議棧與代碼的問題,跟 HTTP 不要緊

天天三分鐘,進階一個前端小 tip 面試題庫 算法題庫

相關文章
相關標籤/搜索