HTTP協議中Content-Type

zyhmz發表於2018-09-16

關於content_type

Content-Type是實體頭域(或稱為實體頭部,entity header)用於向接收方指示實體(entity body)的介質型別的,或稱為資源的MIME型別,現在通常稱media type更為合適。
在響應中,Content-Type標頭告訴客戶端實際返回的內容的內容型別。在請求中 (如POST 或 GET),客戶端告訴伺服器實際傳送的資料型別。

content_type語法

Content-Type: text/html; charset=utf-8 
Content-Type: multipart/form-data; boundary=something[1 to 70 characters]

media-type 資源或資料的 media type
charset 字元編碼標準
boundary 對於多部分(multipart)實體,boundary 是必需的,它用於封裝訊息的多個部分的邊界。其由1到70個字元組成,瀏覽器自動生成,該字符集對於通過閘道器魯棒性良好,不以空白結尾。下面我們舉一個Content-Type 在HTML表單中的例子:

<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

GET常見資料的提交型別

GET方式,是把引數按鍵值對通過QueryString的方式放在URL尾部,比如: http://www.example.com/test.html?a=1&b=2 ,預設的Content-Type為“application/x-www-form-urlencoded”。

POST常見資料的提交型別

POST方法,通常是把要提交的表單放在一個Form中,指明action後就可以提交資料 。提交資料時需要通過表單enctype屬性(規定在傳送到伺服器之前應該如何對錶單資料進行編碼)來確定編碼型別, 其預設的方式也為”application/x-www-form-urlencoded”。

描述
application/x-www-form-urlencoded 在傳送前編碼所有字元(預設,空格轉換為 “+” 加號,特殊符號轉換為 ASCII HEX 值)
multipart/form-data 不對字元編碼,在使用表單上傳的檔案時,必須使用該值
text/plain 純文字, 空格轉換為 “+” 加號,但不對特殊字元編碼

application/x-www-form-urlencoded

最常見的 POST 提交資料的方式,原生Form表單,如果不設定 enctype 屬性,預設為application/x-www-form-urlencoded 方式提交資料。請求類似於下面這樣(無關的請求頭域已略去):

POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8

name=test&val1=1&val2=%E6%B5%8B%E8%AF%95&val3%5B%5D=2

首先,Content-Type被指定為 application/x-www-form-urlencoded;其次,提交的表單資料會轉換為鍵值對並按照 key1=val1&key2=val2 的方式進行編碼,key 和 val 都進行了 URL 轉碼。大部分服務端語言都對這種方式有很好的支援。一般當我們的key和value中遇到中文和一些特殊字元的時候([ ])就進行URL轉碼。

multipart/form-data

另一個常見的 POST 資料提交的方式, Form 表單的 enctype 設定為multipart/form-data,它會將表單的資料處理為一條訊息,以標籤為單元,用分隔符(這就是boundary的作用)分開,類似我們上面Content-Type中的例子。
 由於這種方式將資料有很多部分,它既可以上傳鍵值對,也可以上傳檔案,甚至多個檔案。當上傳的欄位是檔案時,會有Content-Type來說明檔案型別;Content-disposition,用來說明欄位的一些資訊。每部分都是以 –boundary 開始,緊接著是內容描述資訊,然後是回車,最後是欄位具體內容(欄位、文字或二進位制等)。如果傳輸的是檔案,還要包含檔名和檔案型別資訊。訊息主體最後以 –boundary– 標示結束。

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/png

------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

application/json

Content-Type: application/json 作為響應頭比較常見。實際上,現在越來越多的人把它作為請求頭,用來告訴服務端訊息主體是序列化後的 JSON 字串,其中一個好處就是JSON 格式支援比鍵值對複雜得多的結構化資料。 這個Content-Type是對應了postman中raw資料格式。

POST /api/v1/quiz/questionnaire HTTP/1.1
Host: djigo-hk.djiservice.org
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: 844ba7ff-9478-3924-d52e-07a79afa9d71

{"lang":"en","product_type":"42","enc_sn":"c40ffc84b2dd0a8db6dbe10a3bf7254b5fd3511a","local":"CN"}

binary (application/octet-stream)

在Chrome瀏覽器的Postman工具中,還可以看到”binary“這一型別,指的就是一些二進位制檔案型別。如application/pdf,指定了特定二進位制檔案的MIME型別。就像對於text檔案型別若沒有特定的子型別(subtype),就使用 text/plain。類似的,二進位制檔案沒有特定或已知的 subtype,即使用 application/octet-stream,這是應用程式檔案的預設值,一般很少直接使用 。

對於application/octet-stream,只能提交二進位制,而且只能提交一個二進位制,如果提交檔案的話,只能提交一個檔案,後臺接收引數只能有一個,而且只能是流(或者位元組陣列)。

很多web伺服器使用預設的 application/octet-stream 來傳送未知型別。出於一些安全原因,對於這些資源瀏覽器不允許設定一些自定義預設操作,導致使用者必須儲存到本地以使用。一般來說,設定正確的MIME型別很重要。

相關文章