HTTP協議中的GET、POST請求方法的區別

  • 2019 年 12 月 15 日
  • 筆記

在我們日常打開網頁、對接接口時,使用到的一般都是HTTP協議。

HTTP 的工作方式是客戶端與服務器之間的請求-響應。

HTTP 請求方法有:HEAD、PUT、DELETE、OPTIONS、CONNECT

兩種最常被用到的HTTP方法是:GETPOST

本篇文章講講GETPOST兩種請求方法的區別。

在瀏覽器上表現的區別

GET

  • GET 請求可被緩存
  • GET 請求保留在瀏覽器歷史記錄中
  • GET 請求可被收藏為書籤
  • GET 請求參數在URL中的是可見的
  • GET 請求有長度限制

POST

  • POST 請求不會被緩存
  • POST 請求不會保留在瀏覽器歷史記錄中
  • POST 不能被收藏為書籤
  • POST 請求參數在URL中的是不可見的
  • POST 請求對數據長度沒有要求

在瀏覽器上的表現是最表面的,所以大部分的人都已經知道。

簡單的就不再說了,這裡再說說請求參數的可見性和容易讓人產生誤區的數據長度限制

請求參數可見性

在GET請求中,查詢字符串是在 GET 請求的 URL 中發送的

index.php?content=這是get方式裏面的一個字段的值

get方式請求頭和請求體

在POST請求中,查詢字符串是在 POST 請求的 HTTP 消息主體中發送的

POST index.php HTTP/1.1  Host: www.siammm.cn    content=這是post方式裏面的一個字段的值

post方式請求頭和請求體

因為post請求是將參數放在HTTP主體中,所以在常規瀏覽器地址欄上是看不到參數的,這就是請求參數在URL中的可見性的不同。

兩種請求方法請求頭和請求體的對比 可以看到參數存放位置不一樣

數據長度限制

從上面的請求參數可見性我們已經知道

GET請求的所有參數都是在URL中發送的

我們常說的GET請求有數據長度限制,其實那只是瀏覽器對URL長度的限制

嗯,這裡要看清一個點:是瀏覽器

而不是HTTP協議的規定,同時在web服務器上也有對於長度的限制(這些下面的文章會講)

因為post請求是將參數放在HTTP主體中,所以不會受到此限制

不同的瀏覽器對於URL長度的限制是不同的,這個可以自行測試得出

首先:我們找到一篇長文章。(文章可以從短到長進行測試,會從正常搜索然後到達url長度限制)

然後打開https://www.baidu.com/s?wd=文章內容

這個網址,進行百度搜索。

看圖片上的文字說明

把搜索內容替換成超級長的文章,再怎麼按回車或者跳轉按鈕都沒效果,頁面還是保留一開始的。

也就是說url的長度已經到達了瀏覽器的限制,所以瀏覽器不處理該請求了。

這張截圖是在win10自帶的Edge測試的,同時在搜狗瀏覽器也是一樣的情況。

但是在谷歌Chrome瀏覽器就是另一種場景了。瀏覽器會正常跳轉,但是卻不能正常響應。(該情況涉及到的知識,在下面會講)

先附帶一下百度上提供的資料

各個瀏覽器對於url長度的限制

  1. IE瀏覽器對URL的長度現限制為2048位元組(自己測試最多為2047位元組)。
  2. 360極速瀏覽器對URL的長度限制為2118位元組。
  3. Firefox(Browser)對URL的長度限制為65536位元組。
  4. Safari(Browser)對URL的長度限制為80000位元組。
  5. Opera(Browser)對URL的長度限制為190000位元組。
  6. Google(chrome)對URL的長度限制為8182位元組。

在http協議上的規定

HTTP 協議沒有規定URL的最大長度,也沒有規定HTTP請求體的最大長度。

所以在HTTP協議上,對於GET請求和POST請求的數據長度,是沒有限制的。

但規定服務器如果不能處理太長的URL,就得返回414狀態碼(Request-URI Too Long)。

這也是我們上面說到的,在谷歌Chrome瀏覽器中,會正常跳轉,但卻無法正常響應的結果。

請注意,該結果不是由http協議直接返回,而是規定服務器可以這樣子處理(不是強制性 看你web服務器想要處理多長的url),所以該情況是屬於web服務器上的限制,在下面知識會繼續講解

在web服務器配置限制url長度

如果請求正常通過了瀏覽器的限制,則會發送到web服務器上了(如apache nginx)

在進入web服務器時,也需要進行一次限制的檢測。

如果我們的服務器不想服務那麼長的url,可以在這裡通過修改配置參數,來決定最大接收的長度。

如果超過該長度,則遵循HTTP協議,返回414狀態碼,返迴響應並終止此次請求。

以nginx為例

在nginx的配置參數中,有兩個配置項可以決定要服務的url長度。

因為url長度是屬於http請求頭的一部分,所以配置項上的體現是以控制請求頭最大長度的。

這兩個配置項是

client_header_buffer_size  large_client_header_buffers

首先看第一個參數:client_header_buffer_size

當請求進來的時候,web服務器會根據這個參數分配一塊內存,用來容納請求的請求頭。

接着是第二個參數:large_client_header_buffers

如果分配的內存無法容納請求頭,則會根據該參數的,再次分配大一點的內存。

如果還是不夠容納,則已經超出了web服務器設置的服務長度,就會返回給客戶端414狀態碼。

如果只把client_header_buffer_size設置小了,large_client_header_buffers還是很大的話是沒有用的,還會浪費多一次分配內存的操作。

我這裡將兩個參數都設置成了1k

client_header_buffer_size 1k;  large_client_header_buffers 4 1k;

(改完配置記得重啟服務器)

然後進行一個簡單的get請求,帶上1024個位元組的參數(或者更長),服務器返回414 Request-URI Too Large

到這裡,在服務器上限制get傳遞的數據長度的操作就完成了。

如果是apache或者其他的web服務器,也是一樣的原理來進行設置。

總結

  • GET 請求會被瀏覽器緩存,POST 請求不會
  • GET 請求會被瀏覽器保留在歷史記錄中,POST 請求不會
  • GET 請求可以被瀏覽器收藏為書籤,POST 請求不能
  • GET 請求參數在URL中可見,POST 請求參數不能
  • GET 請求對數據長度有要求,POST 請求沒有(這裡指的是瀏覽器對url長度的要求)
  • 在HTTP協議中,對於GET、POST的數據長度是沒有限制的
  • 在WEB服務器中,可以通過配置參數來決定要服務的URL長度限制(通過是控制最大請求頭的長度)POST請求是將參數放在請求體中,所以不受該長度限制
  • 如果WEB服務器不能處理過長的URL,根據HTTP協議需要返回414狀態碼。