搞定Multipart
Multipart解決了在一個HTTP請求里存放多種數據的問題,使得在一個HTTP請求里同時傳輸JSON和二進制數據成為可能,因此multipart大量應用在表單中。本文嘗試用最簡單的方式講解在AJAX時代的multipart實踐。
HTTP請求
Multipart有幾個重要的點:
- 請求的Content-Type必須為multipart/form-data,后面必須跟用於區分各個part的boundary
- 每個part以boundary開始,后面跟Content-Disposition:form-data以及part的name,以及可選的filename
- 每個part有可選的Content-Type
前端
前端可以使用FormData來表示multipart
var formData = new FormData();
formData.append("username", "Groucho");
formData.append("accountnum", 123456); // number 123456 is immediately converted to a string "123456"
// HTML file input, chosen by user
formData.append("userfile", fileInputElement.files[0]);
// JavaScript file-like object
var content = '<a id="a"><b id="b">hey!</b></a>'; // the body of the new file...
var blob = new Blob([content], { type: "text/xml"});
formData.append("webmasterfile", blob);
var request = new XMLHttpRequest();
request.open("POST", "http://foo.com/submitform.php");
request.send(formData);
后端
以應用最廣泛的的Spring Boot為例。
-
可以使用
@RequestParam
或者@RequestPart
來標記multipart中的part,兩者的區別是,當參數類型不是String
或者Multipart
時,@RequestParam
使用Converter
或者PropertyEditor
進行轉換,而@RequestPart
使用HttpMessageConverters
進行轉換。HTTPMessageConverters
依賴Content-Type
來選擇converter,同時@RequestBody
也使用HTTPMessageConverters
。因此,如果參數是key=value
形式的,選擇@RequestParam
,如果參數是JSON或者XML,選擇@RequestPart
-
由於
HTTPMessageConverters
依賴Content-Type
,因此對於非String
/MultipartFile
/Part
類型的參數,必須在請求中指定Content-Type
,前端指定Content-Type
的方法見代碼示例 -
由於自己實現
Converter
或者PropertyEditor
也是有一定代碼量的,而且現在都用JSON傳輸數據,所以更推薦使用@RequestPart
PS:
如果您覺得我的文章對您有幫助,請關注我的微信公眾號,謝謝!