《上传那些事儿之Nest与Koa》——文件格式怎么了!

转载自:juejin - 马睿不想说话
概要本文主要针对在使用node作为服务端接口时,前端上传上传文件至node作为中转,再次上传至oss/cdn的场景 。以及针对在这个过程中,需要对同一个文件进行不同形式之间转换的问题 。
Blob、File、Buffer与stream在解答上述问题之前,我们要先了解一下Blob、File、Buffer与stream这四者分别是什么 。以及这四者的关系是什么样的 。
Blob

Blob 对象表示一个不可变、原始数据的类文件对象 。
这是MDN对Blob的说明 。简而言之,所有的“数据”都可以用blob的格式进行存储,而且不一定是 JavaScript 原生格式的数据 。包括但不仅限于文本、二进制、文档流等 。而通过Blob的实例方法(Blob.prototype.arrayBuffer()Blob.prototype.stream()),我们还可以将blob转换为Buffer和ReadableStream 。
FileFile接口基于 Blob,继承了 blob 的功能并将其扩展以支持用户系统上的文件 。接口提供有关文件的信息,并允许网页中的 JavaScript 访问其内容,且可以用在任意的 Blob 类型的 context 中 。需要注意的一点是,File并没有任何定义方法,而是只从Blob继承了slice方法 。
BufferBuffer是数据以二进制形式临时存放在内存中的物理映射 。在Nodejs中,Buffer类是用于直接处理二进制数据的全局类型 。它可以以多种方式构建 。
streamNode.js 中有四种基本的流类型:
  • Writable: 可以写入数据的流(例如, fs.createWriteStream()) 。
  • Readable:可以从中读取数据的流(例如, fs.createReadStream()) 。
  • Duplex: 两者都是Readable和的流Writable(例如, net.Socket) 。
  • TransformDuplex可以在写入和读取数据时修改或转换数据的流(例如,zlib.createDeflate()) 。
开发前的规划在我们进行文件上传的过程中,经历了两个阶段:
  1. 获取前端上传的文件
  2. 处理文件后,调用内部服务上传至cdn
其实这样看来的话,这是很简单的两个阶段,我们只需要拿到前端的文件后传递给另外一个接口就可以了,可是在这个过程中,有几个我们不得忽视的问题:
  1. 我们的node服务中获取到的前端上传的文件到底是什么格式?
  2. 我们进行上传oss/cdn的接口,需要我们上传的文件格式又是什么样的?
  3. 文件名称如何保持不变/如何进行混淆?
  4. 如何完成文件格式的校验或过滤?
只有在考虑清楚了以上这些内容的处理之后,才应该来考虑我们接口本身的业务逻辑的完善与开发 。
开发中的问题【《上传那些事儿之Nest与Koa》——文件格式怎么了!】由于一些内部原因,Node端的开发经历了从koa2到express的重构 。所以针对两个框架的文件处理,我也都有幸(bushi)全都经历了一次 。
node上传格式由于上传至oss的第三方接口可以在前端调用,也可以在node中进行调用,所以在Postman中可以模仿上传过程,由此可以看到第三方接口真正需要我们传入的其实是一个ReadStream格式的文件 。所以我们的目标也很简单,那就是无论我们获取到什么格式的文件,都转换成为ReadStream格式即可 。
《上传那些事儿之Nest与Koa》——文件格式怎么了!

文章插图
koa2不同于在koa中使用koa-bodyparser模块来完成post请求的处理;在koa2中,使用koa-body模块不仅可以完成对于post请求的处理,同时也能够处理文件类型的上传 。
在这种情况下我们只需要通过

经验总结扩展阅读