我們會常常看到 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}-- ```