天天看點

GET和POST的差別

GET和POST的差別

超文本傳輸協定

HTTP

的設計目的是保證用戶端與服務端之間的通信,

HTTP

協定的工作方式是用戶端與服務端之間的請求響應,在用戶端與服務端進行請求響應時最常用的兩種方法就是

GET

POST

差別

  • GET

    是安全的、幂等的,而

    POST

    是 不安全的、不幂等的。
  • GET

    在浏覽器回退或者重新整理時是無害的,而

    POST

    會再次送出資料請求。
  • GET

    産生的

    URL

    位址可以作為書簽儲存,而

    POST

    不行。
  • GET

    請求會被浏覽器主動

    cache

    ,而

    POST

    不會主動緩存。
  • GET

    請求隻能進行

    url

    編碼,而

    POST

    支援多種編碼方式。
  • GET

    請求參數會被完整保留在浏覽器曆史記錄裡,而

    POST

    中的參數不會被保留。
  • GET

    請求在

    URL

    中傳送的參數長度受

    URL

    長度限制,而

    POST

    的大小取決于後端配置。
  • GET

    參數隻接受

    ASCII

    字元的資料類型,而

    POST

    沒有限制,可以傳輸二進制資料。
  • GET

    POST

    更不安全,因為參數直接暴露在

    URL

    上,是以不适合傳遞敏感資訊。
  • GET

    參數通過

    URL

    傳遞,直接可見,

    POST

    的參數放在

    Request body

    中,不直接可見。

詳解

上述的差別都是

GET

POST

在浏覽器中的具體實作上的差別,例如現在廣泛使用的

Promise

就是各種對于

Promise/A+

的規範

promisesaplus.com

的實作,在

HTTP/1.1

的規範的征求意見稿

RFC

中提到了語義這個詞語,語義定義了一個類型的請求應該具有什麼樣的,例如

GET

的語義就應該是擷取資源,

POST

的語義就是修改資源,如果在符合文法的前提下實作違背語義的行為也是可以做到的,例如使用

GET

修改資源或者使用

POST

擷取資源,甚至使用

GET

發送

body

(這需要服務端能夠配合解析),這是合法的請求但是這是不符合語義的請求,而且很有可能會帶來一些副作用,是以在本質上

GET

POST

的差別是其語義的差別,甚至可以了解為

GET

POST

并沒有什麼差別,隻要用戶端與服務端能夠配合發送與接收即可,一個敢發一個敢收就可以了,而上文所述的差別主要是在浏覽器中具體實作上的差別。

關于安全性與幂等性,安全性是指通路接口時不會對服務端資源狀态發生改變,幂等性是指對于同一接口的

URI

多次通路時,得到的資源狀态是相同的。

  • GET

    : 安全的,幂等的,用于讀取資源。
  • POST

    : 不安全的,不幂等的,用于服務端自動産生的執行個體号建立資源,更新部分資源。
  • PUT

    : 不安全的,幂等的,用于用戶端的執行個體号建立資源,更新資源。
  • DELETE

    : 不安全的,幂等的,用于用戶端執行個體号删除資源。

在浏覽器點選後退操作時,如果将要傳回的頁面是

GET

請求的,那麼将會安全的進行回退,如果将要傳回的頁面是

POST

請求的,例如使用

<form>

method

POST

去送出資料并跳轉頁面的話,浏覽器會發出一個是否再次送出表單的确認提示。

關于

GET

POST

送出的參數長度的限制問題,

GET

是通過

URL

送出資料,是以

GET

可送出的資料量就跟

URL

所能達到的最大長度有直接關系,實際上

HTTP

協定對

URL

長度是沒有限制的,但是在各種浏覽器中對于

URL

長度是有限制的,而且限制的長度是不同的,一般使用不超過

4K

,此外服務端也會對于

URL

有各自的限制,當然服務端可以接收的

URL

長度大小是可以配置的,同樣的,

HTTP

協定沒有對

POST

進行任何限制,

POST

送出的資料大小一般是受伺服器的主動配置來限定大小。

關于敏感資訊不要使用

GET

進行傳輸主要有兩個方面的考慮,首先使用

GET

傳輸敏感資訊會直接暴露在

URL

上,會直接可見,此外使用

GET

傳輸的參數會被直接儲存在浏覽器的曆史記錄中以及伺服器的日志中,當然

HTTP

協定本身就是一個明文傳輸的協定,無論是使用

GET

還是

POST

在中間人攻擊等情況下都是能夠拿到傳輸的資料的,如果需要避免中間人等攻擊需要使用

HTTPS

進行資料的加密傳輸。

GET

發送一個請求,

POST

發送兩個請求的問題,同樣這也是各種浏覽器對于

HTTP

協定的具體實作的案例,而不涉及

GET

POST

的本質差別,關于這個具體的實作在各種浏覽器上的表現并不相同,主要是浏覽器的網絡請求底層對于請求上優化的實作,例如需要使用

POST

傳輸一個大檔案,那麼浏覽器就有可能首先發送一個資料包并攜帶少量資料去檢測服務端是否能夠接收這個檔案,服務端在解析上傳的檔案時,總是會先完全解析全部的請求頭部,伺服器端總是希望能夠了解請求的控制資訊後,就能決定這個請求怎麼進一步處理,是拒絕還是接收,如果服務端允許接收這個檔案那麼用戶端會繼續發送資料進行上傳操作,如果服務端拒絕了就直接中斷上傳,這樣用以節省提高資料吞吐和降低帶寬的浪費。在本質上這和

HTTP

協定無關,這是浏覽器在具體實作上做的一些優化,例如在内部設定一次

POST

的資料超過

1KB

就先隻發請求頭,否則就一次性全發,用戶端甚至還可以做一些

Adaptive

的政策,統計發送成功率,如果成功率很高,就總是全部發等等。不同浏覽器可以有各自的不同的方案,不管怎樣做,優化目的總是在提高資料吞吐和降低帶寬浪費。無論浏覽器如何發送其總是符合

HTTP

協定的,是具體實作而不涉及

GET

POST

的本質差別。

每日一題

https://github.com/WindrunnerMax/EveryDay
           

參考

https://zhuanlan.zhihu.com/p/25028045
https://www.zhihu.com/question/28586791
https://mp.weixin.qq.com/s?__biz=MzI3NzIzMzg3Mw==&mid=100000054&idx=1&sn=71f6c214f3833d9ca20b9f7dcd9d33e4
           
下一篇: DNS解析過程