理解 HTTP 中的 multipart/form-data
HTTP 是一种基于请求-响应模型的网络通信协议,主要用于 Web 中客户端和服务器之间通信的数据传输。事实上,如今的互联网就是构建在 HTTP 之上的。基于请求-响应模式的通信方式很简单,客户端向服务器发送请求,服务器处理请求并进行响应。
HTTP 其实并不关心我们想要传输的是什么类型的数据,因为它什么类型的数据都可以传输!对于客户端或者服务器来说,只需要设置好合适的 Content-Type
,让另一端能够理解数据就可以了。在一个请求中,客户端发送给服务器的数据可以是文本,也可以是图片或者音视频等等。
如果客户端想在一个请求中给服务器发送多种类型的数据呢,该怎么办呢?例如,同时发送用户的基本信息和头像。方法很简单,就是使用 HTTP 的 multipart。
Multipart 消息结构
Multipart 允许客户端在一次 HTTP 请求中发送多个部分(part)数据,每部分数据之间的类型可以不同。Multipart 并不是一种专一的数据类型,它有很多子类型,例如:multipart/mixed
,multipart/form-data
等。
通俗来讲,一个 multipart 消息就是一个大包裹,包裹里面有多个不同类型的消息,每一个消息就是一个 part,每个 part 都会声明自己的消息类型(Content-Type)。除了消息类型,part 还可以附加一些元数据。
Multipart 消息的基本语法结构可以在 RFC2046 中找到:
- 每个 multipart 消息的
Content-Type
都必须包含一个叫做boundary
的参数,boundary
声明了各个 part 之间的边界,记为${boundary}
。实际上,完整的边界定义为:一行由两个-
加上${boundary}
组成的字符串。假设我们在Content-Type
里面指定的boundary=example-part-boundary
,那么按照协议规定,每个 part 之间的分隔行就是:--example-part-boundary
。 - 每个边界之后是一个
CRLF
加下一个 part 的头部信息。如果下一个 part 没有头部信息,边界之后就应该跟两个CRLF
,这样下一个 part 的消息类型就会被认为是text/plain
。 ${boundary}
不能出现在边界之间,并且长度不能超过 70 个字符。- 最后一个 part 之后的边界在末尾多了两个
-
,表示后面不会再有其它的 part 了。这个边界的完整格式为:--${boundary}--
,例如--example-part-boundary--
。
我们会在后面讲 multipart/form-data
给出一个具体的示例。
multipart/form-data
Multipart 的使用在 Web 应用程序中很常见。使用 multipart 频率最高的地方大概就是 Web 表单了,在表单提交时,文件的上传就是通过 Multipart 来实现的。
并不是所有的表单提交都会使用 multipart,如果表单只包含基于文本的输入组件(例如输入框、单选框等),浏览器会将这些数据以 key=value
的形式组织,使用一种被称为 application/x-www-form-urlencoded
的 Content-Type
传输。
如果表单中包含文件或图片等不能被编码成文本的元素,浏览器就会使用 multipart/form-data
向服务器传输数据。
下面是一个使用 multipart/form-data
传输用户信息的例子:
POST /profile HTTP/1.1
HOST: example.com
Content-Type: multipart/form-data; boundary=example-part-boundary--example-part-boundary
Content-Disposition: form-data; name="username"
Content-Type: text/plainNicholas
--example-part-boundary
Content-Disposition: form-data; name="address"
Content-Type: application/json{"country": "China","city": "Beijing"
}
--example-part-boundary
Content-Disposition: form-data; name="avatar"; filename="my_avatar.jpeg"
Content-Type: image/jpeg<binary-image data>
--example-part-boundary--
在上面这个请求中:
Content-Type: multipart/form-data; boundary=example-part-boundary
表示这个请求的的消息类型是multipart-form-data
,每个 part 之间的边界为example-part-boundary
。- 这个请求总共包含三个 part:
- 第一个 part 的类型为
text/plain
,它在表单上对应的key
为username
,value
为Nicholas
。 - 第二个 part 的类型为
application/json
,它在表单上对应的key
为address
。 - 第三个 part 的数据类型为
image/jpeg
,它在表单上对应的key
为avatar
,并且 part 的头部还附加了文件名相关的元数据filename="my_avatar.jpeg
。
- 第一个 part 的类型为
- 最后面的
--example-part-boundary--
表示整个 multipart 消息的结束。
总结
Multipart 是一种常见的数据格式,常用于上传文件和发送包含多种数据类型的单个请求。正确地使用 multipart 可以方便地实现多种数据的传输,提高数据传输效率和用户的使用体验,减少服务器的请求次数。
但是,在使用 multipart 的时候,客户端必须正确地设置 Content-Type
请求头,包含 boundary
参数,并且 boundary
参数的内容不能和请求体内的内容重复。服务器收到请求后,需要根据 Content-Type
设置的 boundary
来解析请求体各个部分的内容。
理解 HTTP 中的 multipart/form-data相关推荐
- 获取referer中的请求参数_Servlet获取AJAX POST请求中参数以form data和request payload形式传输的方法...
本文实例讲述了Servlet获取AJAX POST请求中参数以form data和request payload形式传输的方法.分享给大家供大家参考,具体如下: HTTP请求中,如果是get请求,那么 ...
- vue axios POST请求中参数以form data和request payload形式的原因
HTTP请求中,如果是get请求,那么表单参数以name=value&name1=value1的形式附到url的后面,如果是post请求,那么表单参数是在请求体中,也是以name=value& ...
- AJAX POST请求中參数以form data和request payload形式在servlet中的获取方式
HTTP请求中,假设是get请求,那么表单參数以name=value&name1=value1的形式附到url的后面,假设是post请求,那么表单參数是在请求体中,也是以name=value& ...
- 1. 恼人的Multipart form data
文章目录 1. 概述 2. 问题 3. 解决方案 3.1 解决方案一 3.2 解决方案二 3.3 解决方案三 4. 总结 1. 概述 我目前在公司负责开放平台项目,使用spring-cloud-gat ...
- 理解D3中的数据连接(data join)和选取(selection)是怎么工作的
了解过D3的同学,对下边的这张图片想必都很熟悉 D3是data-diven-document的意思,那么到底什么是数据驱动文档呢?D3是怎样把数据跟dom元素连接到一起的? 一般是分为三步: sele ...
- flux读取不到数据_WebFlux 中form data获取不到参数问题
Spring WebFlux 中, request.queryParams 只能获取到 查询参数, 对于 form 提交的参数无法进行参数自动装载 处理方式有两种: 一. 自定义 ArgumentRe ...
- html+form+multipartform-data,表单 – 如何处理node.js中的multipart / form-data
以下链接重复提问. 这是一个例子: // Expose modules in ./support for demo purposes require.paths.unshift(__dirname + ...
- form data和request payload的区别
2019独角兽企业重金招聘Python工程师标准>>> HTML <form> 标签的 enctype 属性 在下面的例子中,表单数据会在未编码的情况下进行发送: < ...
- form 中Enctype=multipart/form-data 的作用
form 中Enctype=multipart/form-data 的作用 ENCTYPE="multipart/form-data"用于表单里有图片上传. <form na ...
最新文章
- linux python版本_linux下更新Python版本并修改默认版本
- android studio中如何设置注释模板
- cmd不是内部命令解决方法
- 面试:什么是序列化,怎么序列化,为什么序列化,反序列化会遇到什么问题,如何解决?...
- Boost:boost::bimaps::unordered_multiset_of的测试程序
- 【转】【MySQL】运行原理(四):重做日志(redo log),回滚日志(undo log),二进制日志(binlog)
- BitmapFactory.Options详解
- 浙大PAT的大量感悟
- RabbitMQ + ELK 搭建日志平台
- matlab2018安装摄像头驱动以及如何调用摄像头
- Java对接某地联通API接口02---API接口获取验证码
- 怎样更改计算机应用图标,win7如何更改软件图标_win7修改应用程序图标的教程
- Excel遇到错误div/0显示为0或者不显示
- 一寸光阴一寸金——《波波侃项目之时间管理》
- Map.Entry和Map中的map.keySet()、map.entrySet()详解
- python 将单词分割成字母_拆分两个字母创建单词python 3
- OSI七层网络模型详解!
- RocketMQ事务消息
- Quaternion to angular velocity. 四元数 角速度
- java计算机毕业设计新能源汽车租赁管理系统源程序+mysql+系统+lw文档+远程调试