005-四種常見的 POST 提交數據方式

一、http請求方法

HTTP Method RFC Request Has Body Response Has Body Safe Idempotent Cacheable
GET RFC 7231 Optional Yes Yes Yes Yes
HEAD RFC 7231 No No Yes Yes Yes
POST RFC 7231 Yes Yes No No Yes
PUT RFC 7231 Yes Yes No Yes No
DELETE RFC 7231 No Yes No Yes No
CONNECT RFC 7231 Yes Yes No No No
OPTIONS RFC 7231 Optional Yes Yes Yes No
TRACE RFC 7231 No Yes Yes Yes No
PATCH RFC 5789 Yes Yes No No No

二、消息格式

客戶端和服務器經過發送純文本(ASCII)消息進行通訊。客戶端向服務器發送請求,服務器發送響應。html

2.一、請求消息

  • 請求行(例如,GET /images/logo.png HTTP / 1.1,它從服務器請求名爲/images/logo.png的資源)。
  • 請求標頭字段(例如,Accept-Language:en)。
  • 空行。
  • 可選的消息體

2.二、響應消息

  • 狀態行,包括狀態代碼和緣由消息(例如,HTTP / 1.1 200 OK,表示客戶端的請求成功)。
  • 響應頭字段(例如,Content-Type:text / html)。
  • 空行。
  • 可選的消息體

三、POST請求的Content-Type處理

  協議規定 POST 提交的數據必須放在消息主體(entity-body)中,但協議並無規定數據必須使用什麼編碼方式。服務端一般是根據請求頭(headers)中的 Content-Type 字段來獲知請求中的消息主體是用何種方式編碼,再對主體進行解析。因此說到 POST 提交數據方案,包含了 Content-Type 和消息主體編碼方式兩部分。jquery

3.一、application/x-www-form-urlencoded【默認原生】

  瀏覽器的原生 form 表單,若是不設置 enctype 屬性,那麼最終就會以 application/x-www-form-urlencoded 方式提交數據。請求相似於下面這樣(無關的請求頭在本文中都省略掉了):spring

POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8
title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3  

  首先,Content-Type 被指定爲 application/x-www-form-urlencoded;其次,提交的數據按照 key1=val1&key2=val2 的方式進行編碼,key 和 val 都進行了 URL 轉碼。大部分服務端語言都對這種方式有很好的支持。例如 PHP 中,$_POST[‘title’] 能夠獲取到 title 的值,$_POST[‘sub’] 能夠獲得 sub 數組。
  通常默認JQuery 和 QWrap 的 Ajax,Content-Type 默認值都是「application/x-www-form-urlencoded;charset=utf-8」。
  spring MVC中不能使用RequestBody接收,普通的字段接收chrome

3.二、multipart/form-data【文件傳輸】

使用表單上傳文件時,必須讓 form 的 enctyped 等於這個值。直接來看一個請求示例:json

POST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----
WebKitFormBoundaryrGKCBY7qhFd3TrwA
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"
title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/pngPNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

首先生成了一個 boundary 用於分割不一樣的字段,爲了不與正文內容重複,boundary 很長很複雜。而後 Content-Type 裏指明瞭數據是以 mutipart/form-data 來編碼,本次請求的 boundary 是什麼內容。消息主體裏按照字段個數又分爲多個結構相似的部分,每部分都是以 –boundary 開始,緊接着內容描述信息,而後是回車,最後是字段具體內容(文本或二進制)。若是傳輸的是文件,還要包含文件名和文件類型信息。消息主體最後以 –boundary– 標示結束。關於 mutipart/form-data 的詳細定義,請前往 rfc1867 查看。數組

這種方式通常用來上傳文件,各大服務端語言對它也有着良好的支持。
上面提到的這兩種 POST 數據的方式,都是瀏覽器原生支持的,並且現階段原生 form 表單也只支持這兩種方式。瀏覽器

3.三、application/json【推薦】

它做爲請求頭,告訴服務端消息主體是序列化後的 JSON 字符串。因爲 JSON 規範的流行,除了低版本 IE 以外的各大瀏覽器都原生支持 JSON.stringify,服務端語言也都有處理 JSON 的函數。服務器

JSON 格式支持比鍵值對複雜得多的結構化數據app

POST http://www.example.com HTTP/1.1
Content-Type: application/json;charset=utf-8
{"title":"test","sub":[1,2,3]}

這種方案,能夠方便的提交複雜的結構化數據,特別適合 RESTful 的接口。各大抓包工具如 Chrome 自帶的開發者工具、Firebug、Fiddler,都會以樹形結構展現 JSON 數據,很是友好。
spring MVC中使用RequestBody接受便可ide

3.四、text/xml【不推薦】

XML-RPC(XML Remote Procedure Call)。是一種使用 HTTP 做爲傳輸協議,XML 做爲編碼方式的遠程調用規範。典型的 XML-RPC 請求是這樣的:

POST http://www.example.com HTTP/1.1
Content-Type: text/xml
<?xml version="1.0"?>
<methodCall> 
  <methodName>examples.getStateName</methodName> <params>
 <param>
 <value><i4>41</i4></value>
 </param>
 </params>
</methodCall>

XML-RPC 協議簡單、功可以用,各類語言的實現都有。

相關文章
相關標籤/搜索