1996年的
rfc2045
定义了MIME(
Multipurpose Internet Mail Extensions)协议,最初的目的是为了扩展在邮件中传输的数据类型。传输ascii字节以外的信息,后来在HTTP协议中也得到了应用。
MIME使用Content-Type字段来确定在传递的数据类型,在rfc中描述如下:
The purpose of the Content-Type field is to describe the data
contained in the body fully enough that the receiving user agent can
pick an appropriate agent or mechanism to present the data to the
user, or otherwise deal with the data in an appropriate manner. The
value in this field is called a media type.
该字段的目的是为了完整的描述body中的数据,以便于接收方可以选择一个合适的实体或者机制来呈现body中的数据,或者以一种合适的方式来处理body中的数据。这个值被叫做媒体类型。协议的规定就是为了约定好前端和后端之间以http协议交互时的默认处理规则。
我理解的协议的规定是为了让不同厂家的浏览器,不同厂家的web服务都基于标准的协议来实现,才可以让浏览器上能按照协议约定的内容进行展示,并能充分考虑兼容的场景。比如 image/jpeg 就展示图片,
audio类型就调用对应的解析器来播放音乐。
content-type字段在http的响应头中的格式如下
content-type:text/html; charset=UTF-8
type 区分为 discrete-type 离散类型和 composite-type 聚合类型。常见的离散和复合类型如下:
discrete-type := "text" / "image" / "audio" / "video" /
"application" / extension-token
composite-type := "message" / "multipart" / extension-token
rfc2046 中区分了两大类媒体类型,一种是独立的媒体类型,包括了文本类型,图片类型,音频类型,视频类型和应用类型等。另一种是复合的媒体类型,也就是我们所知的multipart类型。multipart类型在5.1节中有明确定义,是在一个http返回中包含了多种媒体类型,不同媒体类型的数据之间以boundary的形式分割。如下为RFC2046中对于 Multipart Media Type的定义。
In the case of multipart entities, in which one or more different
sets of data are combined in a single body, a "multipart" media type
field must appear in the entity's header. The body must then contain
one or more body parts, each preceded by a boundary delimiter line,
and the last one followed by a closing boundary delimiter line.
After its boundary delimiter line, each body part then consists of a
header area, a blank line, and a body area. Thus a body part is
similar to an RFC 822 message in syntax, but different in meaning.
multipart包含如下常见的子类型:
- multipart/alternative [rfc1521]
- 表示同样的信息,以不同的格式或者表现形式在body的多个parts中返回,一般而言在body中的顺序为按复杂程度递增。比如一份word文档,可能以word文档格式,以及富文本格式,以及纯文本格式返回,纯文本格式就会出现在http响应body的第一个部分。这对于不同的客户端,可能支持或者不支持对应格式化的客户端,就都能进行展示,服务端返回数据拥有更好的兼容性。
- multipart/byteranges [rfc2068]
- 字节范围类型的每一个parts包含独立的 Content-Type and Content-Range 字段,这主要是为了传输二进制数据,同时基于Content-Range字段指定每一个parts的二进制数据的长度和偏移量。
- multipart/form-data [rfc1867]
- 该字段是为了让请求方以一种统一的形式实现文件上传的请求,同时提供一种兼容MIME的方式呈现文件上传的响应。
- multipart/mixed [rfc1521]
- mixed应该属于最常用的子类型,当body的每一个parts是独立的时候,且需要以一个特定的顺序被聚合在一起的时候,就使用这种类型。同时当一个UserAgent客户端无法识别multipart子类型的时候,就会默认以multipart/mixed的形式对待。
- x-mixed-replaced
- multipart/related [rfc2112]
- 该类型用于聚合的文件类型,多个文件是聚合在一起用于表达完整的数据信息。通常会有一个“root”body类型作为起始的part。
该段参考自 https://docs.microsoft.com/en-us/previous-versions/office/developer/exchange-server-2010/aa493937(v=exchg.140)
multipart的两种常见应用场景如下:
其一是 以 multipart/form-data的形式,通过http的post请求提交一个表单请求。
其二是 以multipart/mixed; 以一种混合的方式来返回多个独立的数据块。
Content-type: multipart/mixed;boundary=ThisRandomString
--ThisRandomString
Content-type: application/json;
Content-length: xxx;
{jsonbody}
--ThisRandomString
Content-type: application/json;
Content-length: xxx;
{jsonbody}
--ThisRandomString
如果在自己实现httpclient进行解析时,在解析过程中需要提取http返回头中的boundary。基于boundary进行每一块的拆分,然后对拆分后的各个part中共的body的内容逐次进行解析。但要注意content通常以回调的形式返回,一次回调返回的内容是否为完整的part是不确定的,可能不足,也可能包含了多个part。故而需要以类似状态机的形式进行解析。
除了Content-type之外,MIME头部还包括Content-Transfer-Encoding和Content-Disposion。
Content-Transfer-Encoding的应用场景主要在于部分旧的消息转发的实体的实现只能处理US-ASCII字符,即7bit ascii字符。故而为了能够让这些实体正常的传输一些更丰富的数据,需要对这些数据进行一定程度的编码,比如base64 和 quoted-printable都是 MIME定义的合适的编码格式,在服务端回复消息时定义了对应的编码,在客户端识别到传输的数据经过了这些编码,则执行对应的反编码即可。
Content-Disposion 允许标记一条信息用来表示其呈现机制或者是存储方式,最常见的是 Content-Disposition: attachment 指示附件下载时建议的文件名。
但是一般情况下我们实现协议的方式不一定标准的,所以只有对应的app能够解析,而浏览器实际上是无法解析的。可以参考协议的定义修改web服务器的返回实现,来查看浏览器对结果的解析。
参考链接:
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types
https://docs.microsoft.com/en-us/previous-versions/office/developer/exchange-server-2010/aa493937(v=exchg.140)
里有一个 multipart 多部分对象集合类型,这个类型 http 指南里有讲到:MIME 中的 multipart(多部分)电子邮件报文中包含多个报文,它们合在一起作为单一的复杂报文发送。每一部分都是独立的,有各自的描述及内容的集;而在 Mongoose.c 源码里,是这样处理 multipart 类型的报文的,判断头部字段 Content-Type 为 multipart 时,交由相关处理函数进行处理,然后就 return 了,不再后续处理了。表格情形还没试验过,这里主要讲文档情形的。
之前在写一个通用HTTP组件的时候遇到过媒体(Media)类型multipart/form-data的封装问题,这篇文章主要简单介绍一下HTTP协议中媒体类型multipart/form-data的定义、应用和简单实现。
multipart/form-data的定义
媒体类型multipart/form-data遵循multipart MIME数据流定义(该定义可以参考Section 5.1 - RFC2046),大概含义就是:媒体类型multipart/form-data的数据体由多个部分组成
MultipartFile 是 Spring 框架提供的接口,用于简化 multipart/form-data 文件上传处理。它封装了上传文件的所有信息,包括文件名(getOriginalFilename())、类型(getContentType())、大小(getSize())等核心属性,并提供文件内容的读取方法(getBytes()/getInputStream())和保存方法(transferTo())。在 Spring MVC 控制器中,通过@RequestParam注解即可接收单个或多个文件(Mu
文章目录1. 什么是`Multipart`2.包含的对象1) `multipart/form-data`2) `multipart/byteranges`
1. 什么是Multipart
Multipart:多部分对象集合。可以容纳多份类型的数据。
看不懂?没关系,看完例子就懂了
2.包含的对象
multipart/form-data
哎呀,这个我熟,传文件必写的。以前只是知道怎么用,却不知道为什么要这么用。看完这篇文章你就懂了
multipart/byteranges
1) multipart/for
一、postman 模拟Content-Type: multipart/form-data请求头携带Content-Type: multipart/form-data;可以用来上传文件。当然,你也可以不上传文件,上传普通键值对。如下图,使用Postman 模拟提交数据。
MIME 类型分为两类,离散类型和 multipart 类型。离散类型包含一个文档。例如(二进制),image/text/等。Multipart 类型是包含多个部分的文档,这些部分可以有自己的 MIME 类型。有两种 multipart 类型:message/ 和 multipart/ -- 是的,multipart 既是一个类型又是一个类有点混淆。message/类型基本上不再用于任何事情,但multipart/仍然非常重要。你经常看到用于通过 HTML 表单从 Web 浏览器发送文件到服务器。
1.3 multipart类型 MIME邮件中各种不同类型的内容是分段存储的,各个段的排列方式、位置信息都通过Content-Type域的multipart类型来定义。multipart类型主要有三种子类型:mixed、alternative、related。1.3.1 multipart类型基本格式 ● multipart/mixed类型 如果一封邮件中含有附件,那邮件的Conten
一、multipart/mixed 请求multipart/mixed 和 multipart/form-date 都是多文件上传的格式。区别在于:multipart/form-data 是一种特殊的表单上传,其中普通字段的内容还是按照一般的请求体构建,文件字段的内容按照 multipart 请求体构建,后端在处理 multipart/form-data 请求的时候,会在服务器上建立临时的文件夹存...
原因分析:
这是因为请求过来的参数是content-type:multipart/form-data,是表单形式提交过来的,所以问题出现在形参上,去掉形参上的注解即可完成(只需要以spri
POST请求的两种编码格式:application/x-www-urlencoded是浏览器默认的编码格式,用于键值对参数,参数之间用&间隔;multipart/form-data常用于文件等二进制,也可用于键值对参数,最后连接成一串字符传输(参考Java OK HTTP)。除了这两个编码格式,还有application/json也经常使用。...