『速查手册』MIME 多用途互联网邮件扩展

封面.png

『速查手册』MIME 多用途互联网邮件扩展


一、多用途互联网邮件扩展 / 互联网媒体类型

多用途互联网邮件扩展英语:Multipurpose Internet Mail Extensions,缩写:MIME)是一个互联网标准,它扩展了电子邮件标准,使其能够支持:非ASCII字符文本、非文本格式附件(二进位制、声音、图片等)等。
万维网中 HTTP 协议中也使用了 MIME 的框架,标准被扩展为
互联网媒体形式
,用于标识互联网上传输的内容类型,表示文档、文件或字节流的性质和格式,分类标准由互联网号码分配局IANA发布。1996年十一月,媒体类型在“RFC 2045”中被最初定义,当时仅被使用在SMTP协议的电子邮件中。
本文主要讲述的是互联网媒体类型(MIME-type)


二、MIME 命名规则😎

一个MIME类型包括一个类型(type),一个子类型(subtype),此外可以加上一个或多个可选参数(optional parameter),格式为类型名 / 子类型名 [; 可选参数],注意添加可选参数需要以分号分割,MIME 类型对大小写不敏感,但是传统写法都是全小写。
举个栗子text/plain; charset=UTF-8,文件类型为text文本,子类型代表着是纯文字内容,可选参数charset代表文本是以UTF-8编码的。

互联网媒体类型通常与文件拓展名相对应,计算机系统常常通过拓展名来确定一个文件的媒体类型并决定与其相关联的程序软件。


三、MIME 类型列表🍉

此部分正是速查手册发挥威力的地方,如果你正在查找的文件类型不存在这些示例里或文件类型比较特殊,那么在美国互联网号码分配局IANA官方MIME文档或是多伦多大学的学习文档里,可以看到最全的内容类型(Content-Type),希望能够帮助到你。

查阅时需要注意几点:

  • 对于一些应用程序,会有多个不同的扩展名,一般是新旧版本区别,比如微软的 Word、Excel、Powerpoint,在内容类型后会使用「」进行标识,使用时注意区别。
  • 使用application/octet-stream发送未知类型时,出于对资源内容安全考虑(可能是病毒),浏览器不允许设置一些自定义默认操作,需要用户存储到本地使用。
  • 尚未被接受为正式数据类型的子类型 subtype,一般会在名称前加上x-,列如:video/x-flv
  • MIME 根据 type 制定了默认的 subtype,当客户端不能确定 subtype 的情况下,将会使用默认的 subtype 进行处理。Text 默认是text/plain,Application 默认是application/octet-stream,Multipart 默认是multipart/mixed
1)、Type 类型形式
类型名描述
Text用于标准化地表示的文字消息,文字消息可以是多种字符集和或者多种格式
Multipart用于连接消息体的多个部分构成一个消息,这些部分可以是不同类型的资料
Application用于传输应用程序资料或者二进制资料
Message用于包装一个E-mail消息
Image用于传输静态图片资料
Audio用于传输音频或者音声资料
Video用于传输动态影像资料,可以是与音频编辑在一起的视频资料格式
Font用于传输字体文件
Model用于传输3D模型文件
2)、Application 应用文件
内容类型描述
application/ms-excel
application/vnd.ms-excel
application/x-msexcel
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet 「.xlsx, .xlsm」
微软Excel电子表格
application/ms-powerpoint
application/vnd.ms-project
application/vnd.openxmlformats-officedocument.presentationml.presentation 「.pptx, .pptm」
微软PPT演示文档
application/msword
application/vnd.openxmlformats-officedocument.wordprocessingml.document 「.docx, .docm」
微软Word文档
application/pdf
application/x-pdf
PDF文档
application/rtf富文本文档
application/jsonJSON序列化数据
application/zipzip压缩包
application/gzipGzip压缩包
application/x-rar-compressedrar压缩包
application/x-7z-compressed7z、7zip压缩包
application/x-tartar归档包
application/octet-stream任意的二进制文件(通常做为通知浏览器下载文件),如果需要下载的文件不知道什么类型,不妨试试这个说不定有惊喜
application/oggOgg多媒体文件
application/atom+xmlAtom
application/xmlxml
application/xhtml+xmlXHTML
application/x-www-form-urlencoded超文本传输协议HTTP中Post请求的body格式之一,编码方式对于文件这种二进制的数据非常低效
3)、Text 文本
内容类型描述
text/plain纯文字内容
text/htmlHTML
text/cssCSS
text/javascriptjavascript
text/csvCSV文件
text/markdownMarkdown
text/xmlxml
text/vcardvCard电子名片
4)、Video 视频文件
内容类型描述
video/mpegMPEG-1视频文件
video/mp4MP4视频文件
video/oggOgg多媒体文件
video/quicktimeQuickTime视频文件
video/webmWebM视频文件
video/aviavi视频文件
video/x-matroskaMatroska多媒体封装格式
video/x-ms-wmvwmb视频文件
video/x-flvflv视频文件
video/x-matroskamkv视频文件
5)、Audio 数字音频
内容类型描述
audio/mp4MP4音频
audio/mpegMP3或其他MPEG音频
audio/oggOgg音频
audio/vorbisVorbis音频
audio/vnd.rn-realaudio
application/x-pn-realaudio
RealAudio音频
audio/vnd.wave
audio/x-wav
WAV音频
audio/webmWebM音频
audio/flacFLAC音频
audio/aacAAC音频
6)、Image 图像
内容类型描述
image/gifGIF图像文件
image/jpegJPEG图像文件
image/pngPNG图像文件
image/webpSVG向量图像文件
image/tiffTIFF图像文件
image/iconICO图片文件
image/bmpBMP图片文件
7)、Message 邮件信息
内容类型描述
message/rfc822RFC 822形式邮件
message/httpHTTP报文
external-body包含外部引用的消息
message/news包含新闻的消息

邮件类型参考资料较少,上诉描述可能存在不准确的情况,仅供参考。

6)、Model 3D模型
内容类型描述
model/example暂无信息
model/igesIGS文件、IGES文件
model/meshMSH文件,MESH文件
model/vrmlWRL文件,VRML文件
model/x3d+binary表示三维计算机图形的ISO标准,X3DB二进制文件
model/x3d+vrmlX3D ISO标准,表示三维计算机图形,X3DV VRML文件
model/x3d+xmlX3D ISO标准,表示三维计算机图形,X3D XML文件
7)、multipart 复合信息
内容类型描述
multipart/form-data超文本传输协议HTTP中Post请求的body格式之一,一般用于传输文件,编码方式相对高效
multipart/alternativeHTML邮件的HTML形式和纯文本形式,相同内容使用不同形式表示
multipart/mixed包含多个部分的消息

四、Web开发使用Ajax下载文件流「实战场景」

1)、使用 MIME 类型下载文件

在进行 Web 开发时,MIME 比较常用的场景在于上下传输文件(文件IO)以及用户在打开文件选择器时引导用户选择正确的文件类型
注意,在发起文件流资源请求若是缺少 MIME 类型或浏览器认为文件设置了错误的 MIME 类型时,浏览器可能会通过查看资源来进行 MIME 识别嗅探,每一个浏览器在不同的情况下会执行不同的操作。这会有文件识别错误的安全性问题,最好是自己在传输文件流的时候定义请求头Content-Type来设置正确的 MIME,阻止浏览器的 MIME 嗅探行为。
下述代码是下载文件的关键函数,主要依靠<a>标签的download属性,这个属性指示浏览器下载 URL 而不是导航到它,该属性的值将在下载保存过程中作为预填充的文件名。

/**
 * 文件下载函数
 * @param file File或则Blob对象
 * @param filename 文件名, 若未指定则尝试使用file对象name属性
 */
function downloadFile(file, filename) {
  const aEle = document.createElement("a");
  const fileUrl = URL.createObjectURL(file);
  aEle.id = `__download_${Math.random() * 100000}`;
  aEle.style.display = "none";
  aEle.href = fileUrl;
  aEle.download = filename ?? file.name;
  document.body.appendChild(aEle);
  aEle.click();
  document.body.removeChild(aEle);
  URL.revokeObjectURL(fileUrl);
}

来看看下载工作原理,在下述代码里编写一个简单的 markdown 文档内容,并使用浏览器将其下载。
File(bits, name[, options])接口提供有关文件的信息,并允许网页中的 JavaScript 访问其内容,bits参数接受一个ArrayBufferArrayBufferViewBlob,或者String对象的Array或者任何这些对象的组合。

// 不指定后缀, 则File.type属性识别文件类型
let fileName = "基本的客户联系人列表.md";
const data = `
# Markdown
- Markdown是一种轻量级标记语言,创始人为约翰·格鲁伯。它允许人们使用易读易写的纯文本格式编写文档,然后转换成有效的XHTML(或者HTML)文档。[4]这种语言吸收了很多在电子邮件中已有的纯文本标记的特性
- 由于Markdown的轻量化、易读易写特性,并且对于图片,图表、数学式都有支持,目前许多网站都广泛使用Markdown来撰写帮助文档或是用于论坛上发表消息。如GitHub、Reddit、Discord、Diaspora、Stack Exchange、OpenStreetMap 、SourceForge、简书等,甚至还能被用来撰写电子书。
`
const file = new File([data], fileName, {
  // 指定后缀去情况下,type属性失效
  type: "text/markdown"
});
downloadFile(file);

当然,在绝大多数下载文件的场景中,不会只下载一个写死在代码且内容有限的文件,往往都是通过 Ajax 向服务器请求文件流资源再到用户浏览器中下载。
编写一个请求函数,并通过 Ajax 下载一个 Excel 表格模板。值得一提的是,除非文件是简单的文本内容,在大多数情况下都是以文件流进行传输,也就是二进制数据,在保存响应时一定要将其定义成二进制数据类型。

/**
 * 请求函数
 * @param url 请求地址
 * @param config 请求配置项
 * @return {Promise<never>|Promise<unknown>}
 */
function request(url, config = {}) {
  if (config.constructor !== Object) {
    return Promise.reject("请求配置应为对象");
  }

  const {headers, method = "GET", responseType = "json", data} = config;
  const textType = ["text", "json"];

  return new Promise((resolve, reject) => {
    const xml = new XMLHttpRequest();
    xml.open(method, url);
    xml.onreadystatechange = () => {
      if (xml.readyState === XMLHttpRequest.DONE
        && xml.status === 200) {
        // 请求类型影响响应数据
        let responseData = !responseType || textType.includes(responseType)
          ? xml.responseText : xml.response;
        // Json类型尝试解析
        if (/^json$/.test(responseType)) {
          try {
            responseData = JSON.parse(responseData);
          } catch {}
        }
        resolve({
          data: responseData,
          status: xml.status,
          statusText: xml.statusText,
          headers,
          config,
          request: xml
        });
      }
    };

    xml.onerror = () => {
      reject({
        code: "ERR_NETWORK",
        status: xml.status,
        config,
        request: xml
      });
    };

    // 向请求中添加请求头
    if (headers && headers.constructor === Object) {
      for (const [key, value] of Object.entries(headers)) {
        xml.setRequestHeader(key, value);
      }
    }

    // 如果需要,向请求添加responseType
    if (responseType && responseType !== "json") {
      xml.responseType = responseType;
    }

    xml.send(data);
  });
}

/**
 * 文件下载函数
 * @param file File或则Blob对象
 * @param filename 文件名, 若未指定则尝试使用file对象name属性
 */
function downloadFile(file, filename) {
  const aEle = document.createElement("a");
  const fileUrl = URL.createObjectURL(file);
  aEle.id = `__download_${Math.random() * 100000}`;
  aEle.style.display = "none";
  aEle.href = fileUrl;
  aEle.download = filename ?? file.name;
  document.body.appendChild(aEle);
  aEle.click();
  document.body.removeChild(aEle);
  URL.revokeObjectURL(fileUrl);
}

async function execute() {
  const {data} = await request(
    "https://content-prod.officeplus.cn/cms/6d719064-76b5-bd33-fa6d-3a067ae39e28.xlsx?sv=2021-06-08&se=2023-01-17T12%3A43%3A43Z&sr=b&sp=r&sig=PUk8TqTzWZNFCmvdY9Cnkn01EQSDf8yZLH3LqVRfZBg%3D",
    {
      // 二进制文件对象
      responseType: "arraybuffer"
    });
  // 不指定后缀, 则File.type属性识别文件类型
  let fileName = "基本的客户联系人列表";
  const file = new File([data], fileName, {
    // 指定后缀去情况下,type属性失效
    type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    // 老版本xls,MIME浏览器无法自动识别
    // type: "application/ms-excel"
  });
  downloadFile(file);
}

execute();

看到这里,相信你已经掌握了如何根据 MIME 类型在Web开发中下载文件,不妨多多尝试。

2)、在进行Web开发时,关于文件类型,你一定要知道:
  • 在大多数浏览器里,基于文件扩展来假设文件类型,如果在为文件命名时指定了后缀,那么在FileBlob设置的type属性 MIME 值将失效,将根据文件名的后缀进行保存。
  • 假如文件名指定为 deam.txt,但实际上为 PNG 图像文件类型,type属性值给定_image/png_,但这样并不会重新更改为 deam.png 文件,依旧为_text/plain_类型。
  • 使用FileBlobtype属性仅仅对常见文件类型可靠,例如图像、文档、音频和视频,不常见的 MIME 类型会返回空字符串,造成保存的文件没有后缀,如老式 Office 文档.xls文件使用application/ms-excel并不能识别。开发者最好不要依靠这个属性,作为唯一的验证方案。

MIME 类型不仅仅在Web开发中使用,在其他用途上能经常看到其身影,这是一个很通用且伟大的标准。


五、参考资料💘

🍅因发布平台差异导致阅读体验不同,源文贴出:《『速查手册』MIME 多用途互联网邮件扩展》


六、相关博文🍗

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值