如何在HTTP POST請求中發送參數?


Answers

這些值以內容類型指定的格式在請求正文中發送。

通常內容類型是application/x-www-form-urlencoded ,所以請求主體使用與查詢字符串相同的格式:

parameter=value&also=another

當您在表單中使用文件上載時,可以使用multipart/form-data編碼,而不是格式。 它比較複雜,但你通常不需要關心它的外觀,所以我不會展示一個例子,但它可以很好地知道它存在。

Question

在HTTP GET請求中,參數作為查詢字符串發送:

http://example.com/page?parameter=value&also=another

在HTTP POST請求中,參數不會與URI一起發送。

價值在哪裡? 在請求頭中? 在請求正文中? 它是什麼樣子的?




簡短回答:在POST請求中,值是在請求的“正文”中發送的。 通過網絡表單,他們很可能會與媒體類型的application/x-www-form-urlencodedmultipart/form-data 。 被設計為處理網絡請求的編程語言或框架通常會提供這樣的請求的“正確的事情™”,並為您提供易於解碼的值(例如PHP中的$_REQUEST$_POST ,或者cgi.FieldStorage() ,Python中的flask.request.form )。

現在我們稍微離題一下,這可能有助於理解差異;)

GETPOST請求之間的區別在很大程度上是語義上的。 它們也被“使用”的方式不同,這就解釋了值如何傳遞的差異。

GET( 相關RFC部分

執行GET請求時,您可以向服務器請求一個或一組實體。 為了允許客戶端過濾結果,它可以使用URL的所謂“查詢字符串”。 查詢字符串是? 。 這是URI語法的一部分。

因此,從您的應用程序代碼( 接收請求的部分)的角度來看,您需要檢查URI查詢部分以獲取對這些值的訪問權限。

請注意,鍵和值是URI的一部分。 瀏覽器可能對URI的長度施加限制。 HTTP標準規定沒有限制。 但在撰寫本文時,大多數瀏覽器確實限制了URI(我沒有具體的值)。 絕不應該使用GET請求來向服務器提交新信息。 特別是不大的文件。 這就是你應該使用POST或者PUT

POST( 相關RFC部分

執行POST請求時,客戶端實際上是向遠程主機提交新文檔 。 所以, 查詢字符串不(語義上)是有意義的。 這就是為什麼你沒有在應用程序代碼中訪問它們的原因。

POST稍微複雜一點(而且更靈活):

當收到一個POST請求時,你應該總是期待一個“有效載荷”,或者用HTTP的方式來看:一個消息體 。 消息體本身是無用的,因為沒有標準 (據我所知,也許是application / octet-stream?)格式。 正文格式由Content-Type標題定義。 當使用method="POST"的HTML FORM元素時,通常是application/x-www-form-urlencoded 。 如果您使用文件上傳,另一種非常常見的類型是multipart/form-data 。 但可以是任何東西 ,從text/plainapplication/json甚至自定義application/octet-stream

在任何情況下,如果使用無法由應用程序處理的Content-Type發出POST請求,它應該返回一個415狀態碼

大多數編程語言(和/或Web框架)提供了一種將消息體從/最常見類型(如application/x-www-form-urlencodedmultipart/form-dataapplication/json )中multipart/form-data application/x-www-form-urlencoded 。 。 這很簡單。 自定義類型需要更多的工作。

以標準HTML表單編碼文檔為例,應用程序應執行以下步驟:

  1. 閱讀Content-Type字段
  2. 如果該值不是支持的媒體類型之一,則返回帶有415狀態碼的響應
  3. 否則,解碼消息正文中的值。

再次,像PHP這樣的語言或其他流行語言的Web框架可能會為您處理。 這個例外是415錯誤。 沒有框架可以預測您的應用程序選擇支持和/或不支持哪些內容類型。 這取決於你。

PUT( 相關RFC部分

PUT請求的處理方式與POST請求完全相同。 最大的區別是POST請求應該讓服務器決定如何(並且如果有的話)創建一個新的資源。 歷史上(從現在過時的RFC2616開始,它創建一個新的資源作為發送請求的URI的“下級”(子))。

相比之下, PUT請求應該準確地該URI “准予”存儲資源,並準確地存儲該資源。 沒有更多,不少。 這個想法是, 客戶有責任在“推銷”之前製作完整的資源。 服務器應該在給定的URL上按原樣接受它。

因此, POST請求通常不用於替換現有資源。 PUT請求既可以創建也可以替換。

邊注

還有一些“ 路徑參數 ”可用於向遠程設備發送附加數據,但它們非常罕見,所以我不會在這裡詳細討論。 但是,作為參考,這裡是RFC的摘錄:

除了分層路徑中的點段,通用語法將路徑段視為不透明。 生成URI的應用程序通常使用段中允許的保留字符來分隔方案特定的或解引用處理程序特定的子組件。 例如,分號(“;”)和等號(“=”)保留字符通常用於分隔適用於該分段的參數和參數值。 逗號(“,”)保留字符通常用於類似的目的。 例如,一個URI生產者可以使用諸如“name; v = 1.1”的段來表示對“name”的版本1.1的引用,而另一個可以使用諸如“name,1.1”的段來表示相同的段。 參數類型可以通過特定於方案的語義來定義,但是在大多數情況下,參數的語法特定於實現URI解引用算法。




您無法直接在瀏覽器網址欄上輸入。

例如,您可以看到如何使用Live HTTP Headers在Internet上發送POST數據。 結果會是這樣的

http://127.0.0.1/pass.php
POST /pass.php HTTP/1.1

Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://127.0.0.1/pass.php
Cookie: passx=87e8af376bc9d9bfec2c7c0193e6af70; PHPSESSID=l9hk7mfh0ppqecg8gialak6gt5
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
username=zurfyx&pass=password

它說的地方

Content-Length: 30
    username=zurfyx&pass=password

將成為職位價值觀。




HTTP POST中的表單值在請求正文中以與查詢字符串相同的格式發送。

有關更多信息,請參閱spec




某些Web服務要求您分別放置請求數據元數據 。 例如,一個遠程函數可能期望簽名的元數據字符串被包含在一個URI中,而數據被發佈在一個HTTP主體中。

POST請求在語義上可能如下所示:

POST /?AuthId=YOURKEY&Action=WebServiceAction&Signature=rcLXfkPldrYm04 HTTP/1.1
Content-Type: text/tab-separated-values; charset=iso-8859-1
Content-Length: []
Host: webservices.domain.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: identity
User-Agent: Mozilla/3.0 (compatible; Indy Library)

name    id
John    G12N
Sarah   J87M
Bob     N33Y

這種方法在邏輯上將QueryString和Body-Post結合起來,使用單個Content-Type ,這是一個Web服務器的“解析指令”。

請注意: HTTP / 1.1的左邊是#32 (空格),右邊是#10 (換行)。




POST請求中的默認媒體類型是application/x-www-form-urlencoded 。 這是編碼鍵值對的格式。 密鑰可以重複。 每個鍵值對都由一個&字符分隔,並且每個鍵與其值由一個=字符分隔。

例如:

Name: John Smith
Grade: 19

編碼為:

Name=John+Smith&Grade=19

它放在HTTP標頭後的請求主體中。




內容放在HTTP頭之後。 HTTP POST的格式是具有HTTP標頭,後跟空行,後跟請求主體。 POST變量作為鍵值對存儲在主體中。

您可以在HTTP Post的原始內容中看到此內容,如下所示:

POST /path/script.cgi HTTP/1.0
From: frog@jmarshall.com
User-Agent: HTTPTool/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 32

home=Cosby&favorite+flavor=flies

你可以使用像Fiddler這樣的工具來查看這個工具,你可以使用它來觀察通過線路發送的原始HTTP請求和響應有效載荷。