简介

无规矩不成方圆,无标准不成网络通信。正是在各种网络协议和标准的基础之上,才构建了我们现在流行的互联网。今天给大家介绍的就是一个网络标准格式,叫做MIME,它的全称是Multipurpose Internet Mail Extensions,翻译过来就是多用途Internet邮件扩展。

那么有小伙伴开始疑惑了,原来是一个邮件的扩展协议,那么它跟我们使用的Internet网络有什么关系呢?

不急,我们慢慢道来。

MIME详解

在很久很久以前,计算机的一种流行的应用就是发邮件,最开始的时候,计算机世界的编码方式就只有ASCII一种,但是随着时间的推移和各种应用需求的激增,ASCII格式已经不能满足我们的需求了,格式多类型的同时也照成了互相通信之间的困难,于是一个统一的消息格式标准产生了,这个就是MIME。

MIME可以让邮件不仅支持ASCII,还可以支持其他的编码方式。同时支持图片、音频、视频和应用程序等多种附件。

消息体还可以支持多个part的集合,当这样的消息邮件使用MIME格式编码之后,就可以通过标准的邮件协议,比如SMTP、POP、IMAP等进行发送了。

因为MIME是一个标准,所以只要符合这种标准的邮件都能够被解析成功。

很快,MIME就在邮件世界被广泛应用,但是互联网已经发展到使用流行的HTTP协议来访问万维网的时候了,MIME中定义的各种content types很自然的也成了其他协议中使用的content标准。

这种content types是在MIME头中定义的,应用程序接收到content type之后,会根据类型中指定的消息类型,来采用对应的应用程序对消息内容进行解析。

MIME头

MIME头很重要,是应用程序用来判断消息格式的首要依据。MIME头可以包含下面的字段。

MIME-Version

如果存在这个消息头,说明这个消息是遵循的是MIME格式。它的值通常是1.0。

MIME-Version: 1.0

有细心的小伙伴可以能要问了,既然有1.0,那么有没有1.1或者2.0呢?

很抱歉,答案是没有。因为根据MIME 共同创建者 Nathaniel Borenstein 的说法,虽然引入MIME版本号是为了在后续中对MIME进行修改和升级。但是因为MIME规范并没有为未来MIME版本的升级进行良好的设计,所以不同的人可能对MIME版本升级后的处理方式都是不一样的。从而导致在MIME广泛应用的今天,很难对MIME规范进行升级。

所以,就使用1.0吧。

Content-Type

如果属性HTTP协议的同学,对这个头应该很熟悉了吧,这个头表示的是消息体的类型,包含了类型和子类型,比如:

Content-Type: text/plain

我们常说的MIME type就是指这个标签。

下面是常用的MIME type:

说明 后缀 类型
超文本标记语言文本 .html text/html
xml文档 .xml text/xml
XHTML文档 .xhtml application/xhtml+xml
普通文本 .txt text/plain
RTF文本 .rtf application/rtf
PDF文档 .pdf application/pdf
Microsoft Word文件 .word application/msword
PNG图像 .png image/png
GIF图形 .gif image/gif
JPEG图形 .jpeg,.jpg image/jpeg
au声音文件 .au audio/basic
MIDI音乐文件 mid,.midi audio/midi,audio/x-midi
RealAudio音乐文件 .ra, .ram audio/x-pn-realaudio
MPEG文件 .mpg,.mpeg video/mpeg
AVI文件 .avi video/x-msvideo
GZIP文件 .gz application/x-gzip
TAR文件 .tar application/x-tar
任意的二进制数据 application/octet-stream

Content-Disposition

Content-Disposition是在RFC 2183中添加的一个字段,表示的是消息的展示样式。因为之前的消息只是定义了它的消息格式,并没有考虑消息是如何展示的问题,尤其是对于邮件来说。

比如邮件中插入了一个图片,那么这个图片是在我们读消息的时候内联展示呢?还是以附件的形式,必须要用户下载才能看到呢?

如果是在HTTP中,响应头字段Content-Disposition:attachment 通常用作提示客户端将响应正文呈现为可下载文件。通常,当收到这样的响应时,Web浏览器会提示用户将其内容保存为文件,而不是将其显示为浏览器窗口中的页面。

Content-Transfer-Encoding

这个字段是做什么用的呢?

我们知道,随着数据格式越来越多,传统的ASCII已经不能支持庞大的内容表示形式,所以出现了超出ASCII范围的内容表示形式如Unicode。

但是对于SMTP服务器来说,能够传输或者认识的编码是有限的,如果要传输二进制内容,则需要使用一定的transfer encodings方式对二进制内容进行转换。这就是Content-Transfer-Encoding的意义。

根据RFC和IANA的定义,有下面几个transfer encodings方式:

Name Reference
7bit [RFC2045]
8bit [RFC2045]
binary [RFC2045]
quoted-printable [RFC2045]
base64 [RFC2045]

具体transfer encodings的含义,可以参考我后续的文章,这里只做简单的介绍。

对于普通的SMTP服务器来说,可以支持7bit、quoted-printable和base64这三种编码方式。

对于8BITMIME SMTP extension的SMTP服务器来说,还支持8bit这种编码方式。

对于支持BINARYMIME SMTP extension的SMTP服务器来说,还支持binary这种编码方式。

Encoded-Word

根据RFC 2822,确认消息头中的字段名和值必须使用ASCII字符。如果消息中包含非ASCII字符,则需要进行编码。这个编码就是encoded-word 。

编码的格式如下:

"=?charset?encoding?encoded text?=".

charset表示的是原消息的编码,encoding表示的是使用的编码方式,encoded text是编码后的消息。

Multipart messages

最后,介绍一下Multipart messages,我们知道一个消息是有对应的消息类型:Content-Type的。

如果是复杂的消息,那么它里面的消息类型可能不止一种。所以这时候就需要用到Multipart messages,也就是将消息分为多个部分,每个部分都有一个Content-Type。

这种类型在邮件中比较常见。下面是一个Multipart messages的例子,在Content-Type中指定了一个消息的分割标记boundary。

MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=frontier This is a message with multiple parts in MIME format.
--frontier
Content-Type: text/plain This is the body of the message.
--frontier
Content-Type: application/octet-stream
Content-Transfer-Encoding: base64 PGh0bWw+CiAgPGhlYWQ+CiAgPC9oZWFkPgogIDxib2R5PgogICAgPHA+VGhpcyBpcyB0aGUg
Ym9keSBvZiB0aGUgbWVzc2FnZS48L3A+CiAgPC9ib2R5Pgo8L2h0bWw+Cg==
--frontier--

总结

以上就是MIME的基本介绍,在其中,我们提到了几种transfer encodings方法,敬请期待后续文章。

本文已收录于 http://www.flydean.com/12-mime/

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

网络标准之:永远是1.0版本的MIME的更多相关文章

  1. Unity开发:5.0+版本标准资源包无内置问题

    一.问题如下: 在Unity中,一般都会内置有基础的资源包,可以在Assets->Import Package中,点击其下的子项进行导入: 但是我发现,5.0版本与之前的4.x版本相比,安装包变 ...

  2. Nacos发布0.5.0版本,轻松玩转动态 DNS 服务

    阿里巴巴微服务开源项目Nacos于近期发布v0.5.0版本,该版本主要包括了DNS-basedService Discovery,对Java 11的支持,持续优化Nacos产品用户体验,更深度的与Sp ...

  3. 三、主流区块链技术特点及Hyperledger Fabric V1.0版本特点

    一.Hyperledger fabric V1.0 架构 1.逻辑架构: 2.区块链网络 3.运行时架构 二.架构总结 1.架构要点 分拆Peer的功能,将Blockchain的数据维护和共识服务进行 ...

  4. ORACLE RAC 11.2.0.4 CentOS release 6.9 静默安装1.0版本

    RAC11.2.0.4静默安装 1.0版本,20180613 #本文档IP地址使用X隐藏,个人可按照自己的当前环境IP进行适当修改 1. 清除原环境中的单实例软件 #清除原环境: 删除/etc/ora ...

  5. Python3.0版本 从听说python可以做爬虫到自己第一成功做出爬虫的经历

    前言 我自己是个python小白,工作也不是软件行业,但是日常没事时喜欢捣鼓一些小玩意,自身有点C语言基础. 听说python很火,可以做出爬虫去爬一些数据图片视频之类的东东,我的兴趣一下子就来了.然 ...

  6. 003-主流区块链技术特点及Hyperledger Fabric V1.0版本特点

    一.Hyperledger fabric V1.0 架构 1.逻辑架构: 2.区块链网络 3.运行时架构 二.架构总结 1.架构要点 分拆Peer的功能,将Blockchain的数据维护和共识服务进行 ...

  7. Apache Flink 1.9.0版本新功能介绍

    摘要:Apache Flink是一个面向分布式数据流处理和批量数据处理的开源计算平台,它能够基于同一个Flink运行时,提供支持流处理和批处理两种类型应用的功能.目前,Apache Flink 1.9 ...

  8. .NET Core 2.0版本预计于2017年春季发布

    英文原文: NET Core 2.0 Planned for Spring 2017 微软项目经理 Immo Landwerth 公布了即将推出的 .NET Core 2.0 版本的细节,该版本预计于 ...

  9. 【原】迎接微信winphone 5.0 版本的IE10样式兼容

    微信 Android 5.1 和 iPhone 5.1 已正式发布了,据说本12月底,微信将推出 Winphone 5.0版本,全面支持微信支付,它绑定 IE10 浏览器,那么做微信公众号的 H5 页 ...

随机推荐

  1. Mac系统如何显示隐藏文件

    Command+Shift+. 可以显示隐藏文件.文件夹,再按一次,恢复隐藏:finder下使用Command+Shift+G 可以前往任何文件夹,包括隐藏文件夹.

  2. iOS 即使通讯第三方SDK 资料

    第三方即时通讯SDK,下面是一些主流的第三方的即时通讯SDK,尽管不能查看里面的源代码,但通过查看头文件,能为实现自己的即使通讯SDK提供很好的思路.(备用) 容云 容联.云通讯 IMSDK - 轻松 ...

  3. MLlib学习——基本统计

    给定一个数据集,数据分析师一般会先观察一下数据集的基本情况,称之为汇总统计或者概要性统计.一般的概要性统计用于概括一系列观测值,包括位置或集中趋势(比如算术平均值.中位数.众数和四分位均值),展型(比 ...

  4. iOS数据持久化方式及class_copyIvarList与class_copyPropertyList的区别

    iOS数据持久化方式:plist文件(属性列表)preference(偏好设置)NSKeyedArchiver(归档)SQLite3CoreData沙盒:iOS程序默认情况下只能访问自己的程序目录,这 ...

  5. Solution -「CF 494C」Helping People

    \(\mathcal{Description}\)   Link.   给定序列 \(\{a_n\}\) 和 \(m\) 个操作,第 \(i\) 个操作有 \(p_i\) 的概率将 \([l_i,r_ ...

  6. ICLR 2018 | Deep Gradient Compression: Reducing the Communication Bandwidth for Distributed Training

    为了降低大规模分布式训练时的通信开销,作者提出了一种名为深度梯度压缩(Deep Gradient Compression, DGC)的方法.DGC通过稀疏化技术,在每次迭代时只选择发送一部分比较&qu ...

  7. 从零开始, 开发一个 Web Office 套件(4):新的问题—— z-index

    <从零开始, 开发一个 Web Office 套件>系列博客目录 这是一个系列博客, 最终目的是要做一个基于HTML Canvas 的, 类似于微软 Office 的 Web Office ...

  8. DBLink的使用(从A库使用SQL查询B库的数据)

    DBLink的使用 情景:今天我需要从A数据库查询B数据库的数据,进行一些数据比对和联合查询的操作. 所以用到的DBLink,在此记录一下使用流程,希望能够帮助下一个小白,一步到位的解决问题. 一句话 ...

  9. Python小游戏之 - 飞机大战 !

    用Python写的"飞机大战"小游戏 源代码如下: # coding=utf-8 import random import os import pygame # 用一个常量来存储屏 ...

  10. Android SugarORM(3)

    Android Sugar ORM (3) Android Sugar ORM 查询 我们在此之前介绍了一些关于Sugar ORM的简单操作, 现在我们就查询来具体说一下 Sugar ORM中的fin ...