HTTP 的實體首部欄位,用於說明請求或返回的消息主體是何種方式編碼,在 request header(請求頭) 和 response header(響應頭) 裡存在。
幾種常見的類型:瀏覽器的原生 form 表單,如果不設置屬性,那麼最終就會以application/x-www-form-urlencoded方式提交數據,請求如上面的形式:
POST http://www.baidu.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這種方式提交的數據放在 body 裡面,數據按照key1=val1&key2=val2的方式進行編碼,key 和 val 都進行了 url 編碼
multipart/form-data該種方式也是一種常見的 POST 提交方式,通常表單上傳文件時使用這種方式
使用表單上傳時,必須讓 form 的 enctype 等於這個值
<form action="/" method="post" enctype="multipart/form-data">
<input type="text" name="description" value="some text" />
<input type="file" name="myFile" />
<button type="submit">Submit</button>
</form>在請求頭這裡看起來是這樣:
POST /foo HTTP/1.1
Content-Length: 68137
Content-Type: multipart/form-data; boundary=--974767299852498929531610575
--974767299852498929531610575
Content-Disposition: form-data; name="description"
some text
--974767299852498929531610575
Content-Disposition: form-data; name="myFile"; filename="foo.txt"
Content-Type: text/plain
(content of the uploaded file foo.txt)
--974767299852498929531610575--稍微分析下:
首先生成一個 boundary 用於分割不同的欄位,為了避免與正文內容重複,boundary 很長很複雜
然後 content-Type 裡指明了數據是以 multipart/from-data 來編碼,本次請求的 boundary 是什麼內容
消息主體裡按照欄位個數又分為多個結構類似的部分,每部分都是以 --boundary開始,緊接著是內容描述信息,然後是回車,最後是欄位具體內容(文本或二進位)
如果傳輸的是文件,還要包含文件名和文件類型信息。消息主體最後以--boundary-- 標識結束。
關於 multipart/form-data 的詳細定義,可前往 rfc1867 查看
application/jsonapplication/json 作為響應頭,現在越來越多的人把其作為請求頭,用來告訴伺服器消息主體是序列化後的 json 字符串。請求類似下面形式
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 數據,非常友好。
text/xml該種方式主要用來提交 XML 格式的數據,請求形式如下:
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>顯然在 API 方面,現在 JSON 大有取代 XML 的意思,但是 XML 依然有其不可代替的領域。