搞定Multipart

2022-10-09,

搞定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:
如果您觉得我的文章对您有帮助,请关注我的微信公众号,谢谢!

《搞定Multipart.doc》

下载本文的Word格式文档,以方便收藏与打印。