Content-Type簡析

目錄

一:Content-Type

二:常用的類型

2.1 multipart/form-data

2.2 application/x-www-form-urlencoded

2.3 application/json

2.4 text/xml

三:補充說明

3.1.application/octet-stream

3.2.multipart/form-data和application/x-www-form-urlencoded的區別

四:Content-Type設置建議


一:Content-Type

       Content-Type,內容類型,一般是指網頁中存在的Content-Type,用於定義網絡文件的類型和網頁的編碼。在HTTP協議消息頭中,使用Content-Type來表示請求和響應中的媒體類型信息。它用來告訴服務端如何處理請求的數據,以決定瀏覽器將以什麼形式、什麼編碼讀取這個文件,這就是經常看到一些Asp網頁點擊的結果卻是下載到的一個文件或一張圖片的原因。

下面是幾個常見的Content-Type:

1.text/html
2.text/plain
3.text/css
4.text/javascript
5.application/x-www-form-urlencoded
6.multipart/form-data
7.application/json
8.application/xml
... 


二:常用的類型

2.1 multipart/form-data

上圖的form-data就是指的multipart/form-data
這是一個多部分多媒體類型,它是一個常見的 POST 數據提交的方式,它會生成了一個 boundary 用於分割不同的字段。它會將表單的數據處理爲一條消息,以標籤爲單元,用分隔符分開。既可以上傳鍵值對,也可以上傳文件。當上傳的字段是文件時,會有Content-Type來說明文件類型。
注意,當使用表單上傳文件時,必須讓 form 的 enctype 等於這個值。

<form action="/" method="post" enctype="multipart/form-data">
  <input type="text" name="username">
  <button type="submit">Submit</button>
</form>

multipart/form-data用在發送文件的POST包。

這裏假設我用python的request發送一個文件給服務器:

data = {
    "key1": "123",
    "key2": "456",
}

files = {'file': open('index.py', 'rb')}
res = requests.post(url="http://localhost/upload", method="POST", data=data, files=files)
print res

通過工具,可以看到我發送的數據內容如下:

POST http://www.homeway.me HTTP/1.1
Content-Type:multipart/form-data; boundary=------WebKitFormBoundaryOGkWPJsSaJCPWjZP

------WebKitFormBoundaryOGkWPJsSaJCPWjZP
Content-Disposition: form-data; name="key2"
456
------WebKitFormBoundaryOGkWPJsSaJCPWjZP
Content-Disposition: form-data; name="key1"
123
------WebKitFormBoundaryOGkWPJsSaJCPWjZP
Content-Disposition: form-data; name="file"; filename="index.py"

這裏Content-Type告訴我們,發包是以multipart/form-data格式來傳輸,另外,還有boundary用於分割數據。

當文件太長,HTTP無法在一個包之內發送完畢,就需要分割數據,分割成一個一個chunk發送給服務端,

那麼--用於區分數據快,而後面的數據就是標示區分包作用。

 

2.2 application/x-www-form-urlencoded

       上圖的x-www-form-urlencoded就是指的application/x-www-form-urlencoded,

        application/x-www-form-urlencoded是常用的表單發包方式,普通的表單提交,或者js發包,默認都是通過這種方式,

       一般用於表單提交,會將請求參數用key1=val1&key2=val2的方式進行組織和編碼,key 和 val 都進行了 URL 轉碼,並放到請求實體裏面(注意如果是中文或特殊字符如"/"、","、“:" 等會自動進行URL轉碼)。

比如一個簡單地表單:

<form enctype="application/x-www-form-urlencoded" action="http://homeway.me/post.php" method="POST">
    <input type="text" name="name" value="homeway">
    <input type="text" name="key" value="nokey">
    <input type="submit" value="submit">
</form>

那麼服務器收到的raw header會類似:

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate
Accept-Language:zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4,gl;q=0.2,de;q=0.2
Cache-Control:no-cache
Connection:keep-alive
Content-Length:17
Content-Type:application/x-www-form-urlencoded

那麼服務器收到的raw body會是,name=homeway&key=nokey,在php中,通過$_POST就可以獲得數組形式的數據。

 

2.3 application/json

     最常用的。使用這個類型,提交的是序列化後的 JSON 字符串,服務端/客戶端會按json格式解析數據

上圖的的raw,表示可上傳任意格式的文本,可以上傳text、json、xml、html等各種文本類型,一般用來選擇application/json傳入json格式的參數。

private static String postJson(String urlStr, String json) throws IOException {
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setConnectTimeout(8000);
        conn.setReadTimeout(8000);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type","application/json");
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.getOutputStream().write(json.getBytes());

        if(conn.getResponseCode() == 200) {
            BufferedReader
                reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            return response.toString();
        }
        return null;
    }

2.4 text/xml

即傳遞XML格式,在以前比較常用,不接觸老的項目應該用不到。


三:補充說明

3.1.application/octet-stream

上圖binary指的是application/octet-stream
Content-Type爲application/octet-stream時,只可上傳二進制數據,通常用來上傳文件,沒有鍵值,一次只能上傳一個文件。

3.2.multipart/form-data和application/x-www-form-urlencoded的區別

  • multipart/form-data:既可以上傳文件等二進制數據,也可以上傳表單鍵值對,只是最後會轉化爲一條信息。
  • application/x-www-form-urlencoded:只能上傳鍵值對,且鍵值對都是間隔分開。

四:Content-Type設置建議

  1. restful接口(json格式),一般將Content-Type設置爲application/json; charset=UTF-8
  2. 文件上傳,Content-Type設置爲multipart/form-data
  3. 普通表單提交,Content-Type設置爲application/x-www-form-urlencoded


 

參考文章:

https://www.jianshu.com/p/46fec81809df

https://www.jianshu.com/p/bca3d5cca8a2

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章