我們會常常看到 HTML Form 要填上 `enctype` 才可以上傳檔案,究竟 HTML Form 的 `enctype` 是什麼來的呢?
### TL;DR
如果需要文件上傳,你只可以使用 `form-data`。 。 與 `x-www-form-urlencoded` 相比,`form-data` 是一種更高級的數據編碼方式。 您可以將 `x-www-form-urlencode` 視為 `txt` 文件,並將 `form-data` 視為 `html` 文件。最終,它們都提供了一些 `http` 的 payload。
### Content Type
||content-type|
|---|
|x-www-form-urlencoded|application/x-www-form-urlencoded|
|form-data|multipart/form-data; boundary={boundary string}|
瀏灠器通常會自己生成一個分隔的字串,用來分隔每筆傳動的資料,格式通常會是 :
```txt
----WebKitFormBoundaryFasdfWEfawEF3
```
這個字串使用者是可以自訂的。
### Request Payload
假如有以下登入資料 :
|fields|values|
|---|
|username|foo|
|password|bar|
如果以上的 payload 使用 `x-www-form-urlencoded` 方法去表示的話,資料會使用 `encodeURIComponent()` 編碼並變成以下這樣 :
```text
username=foo&password=bar
```
而如果使用 `form-data` 的話,每一組資料 (key, value) 都會有自己的一個 section,並會使用 `{boundary string}` 為作分隔。以下會以 `form-data` 方法再把上面的資料整理一次 :
```text
--{boundary string}
Content-Disposition: form-data; name="username",
foo
--{boundary string}
Content-Disposition: form-data; name="password",
bar
--{boundary string}--
```
如果 `form` 中有上傳檔案的話,內容會像以下 :
```text
--{boundary string}
Content-Disposition: form-data; name="username",
foo
--{boundary string}
Content-Disposition: form-data; name="password",
bar
--{boundary string}
Content-Disposition: form-data; name="file"; filename="image.jpg"
Content-Type: image/jpeg,
binary data...
--{boundary string}--
```
我們把上面的 Body 分成為 4 部份,以下會為每一部份講解 :
### 第 1 部份
這裏儲存著資料 `username` 為 `foo`。
```text
--{boundary string}
Content-Disposition: form-data; name="username",
foo
```
### 第 2 部份
這裏儲存著資料 `password` 為 `bar`。
```text
--{boundary string}
Content-Disposition: form-data; name="password",
bar
```
### 第 3 部份
這裏儲存著上傳檔案的資料,欄位名為 `file`,檔案名為 `image.jpg`。
```text
--{boundary string}
Content-Disposition: form-data; name="file"; filename="image.jpg"
Content-Type: image/jpeg,
binary data...
```
### 第 4 部份
Body 的完結。
```text
--{boundary string}--
```