GET 和 POST 究竟有什麼區別
大家在初學 HTTP 協議的時候,可能從來沒有想到面試的時候每次都會被問到 GET 和 POST 請求的區別吧。今天我們就來尋找一下標準答案。
簡單回憶一下 HTTP
MDN 上對 HTTP 的描述是這樣的:
超文字傳輸協議是用於傳輸諸如HTML的超媒體文件的應用層協議。它被設計用於 Web 瀏覽器和 Web 伺服器之間的通訊,但它也可以用於其他目的。`
其中 HTTP 定義了一組請求方法,以表明要對給定資源執行的操作。這些方法是一組有語義的動詞或名字,主要有 GET/HEAD/POST/PUT/DELETE/CONECT/OPTIONS/TRACE/PATCH
,我們最常用的是 GET 和 POST,MDN 上對 GET 和 POST 用途的描述分別為:
- GET方法請求一個指定資源的表示形式. 使用GET的請求應該只被用於獲取資料.
- POST方法用於將實體提交到指定的資源,通常導致狀態或伺服器上的副作用的更改.
有了這些基礎就對後面的比較有幫助了。
標準回答
- GET在瀏覽器回退時是無害的,而POST會再次提交請求。
- GET產生的URL地址可以被加入到書籤,而POST不可以。
- GET請求會被瀏覽器主動cache,而POST不會,除非手動設定。
- GET請求只能進行url編碼,而POST支援多種編碼方式。
- GET請求引數會被完整保留在瀏覽器歷史記錄裡,而POST中的引數不會被保留。
- GET請求在URL中傳送的引數是有長度限制的,而POST麼有。
- 對引數的資料型別,GET只接受ASCII字元,而POST沒有限制。
- GET比POST更不安全,因為引數直接暴露在URL上,所以不能用來傳遞敏感資訊。
- GET引數通過URL傳遞,POST放在Request body中。
- 大多數瀏覽器通常都會限制url長度在2K個位元組,而大多數伺服器最多處理64K大小的url。
其中比較重要的是1、10。再回答第一條的時候,可以多回答一句,POST請求是冪等的,而GET不是。
RFC7231裡定義了HTTP方法的幾個性質:
- Safe - 安全
安全主要是說一個方法在語義上需要是隻讀的,就是不能修改伺服器狀態(或者說是資料),比如網路爬蟲在爬到這個 URL 的時候,或者使用者在瀏覽器書籤和位址列記憶裡訪問 URL 的時候,不至於對伺服器造成伺服器狀態的的改變。RFC定義,GET, HEAD, OPTIONS 和 TRACE 這幾個方法是安全的。
- Idempotent - 冪等
冪等的概念是指同一個請求方法執行多次和僅執行一次的效果完全相同。這樣比如瀏覽器在返回或者重新整理到有 POST 請求的時候,會給使用者一個提示資訊,防止非冪等的 POST 請求會給修改服務端狀態,而不是使用者想要的效果。安全的方法都是冪等的。RFC 規定 PUT、DELETE 和上面提到的GET、 HEAD、OPTIONS、TRACE 方法都是冪等的。
- Cacheable - 可快取性
一個方法可以被快取,就是在某些情況下可以被快取,比如我們請求頁面時候,一些靜態檔案是可以直接從快取中獲取的,比如 css、js、圖片等檔案。RFC 裡規定 GET,HEAD 和某些情況下的 POST 都是可快取的。
其實 GET 和 POST 更多的區別是在語義上的區別,在語法上的區別並不是重點。因為服務端拿到 GET 資料以後,也可以去修改伺服器狀態。
關於 POST 會發2次請求的爭論
知乎專欄有過 GET 請求和 POST 請求一個本質區別的討論,就是 GET 請求只會發一個請求,而 POST 請求會發兩次 HTTP 報文。最後證明並不算是2者的差別,想吃瓜的群眾可以看下面參考文件中的4和5.