文件上传中间件:koa-multer
前言
文件上传,应该是web应用开发中最常见的动作了,一般有单文件上传、多文件上传、文件与数据一同上传等方式,而
koa
中使用了koa-multer
来进行文件的上传服务,下面让我们来了解一波关于文件上传服务的使用!
如何使用
1 | const Koa = require('koa'); |
以下是对应的输出结果
这里我们定义了两个路由,一个是处理多个文件的,一个是处理单个文件的,而且,通过配置的参数名称,将对应地在请求上下文ctx
中对应存储着相应的字段
往上下文追加的属性
- ctx.request.file/ctx.file: 提交的单个文件
- ctx.request.files/ctx.files: 提交的多个文件
- ctx.request.body: 提交上来的非文件数据
源码学习
由于
koa-multer
的实现主要是基于espress-multer
来实现的,因此关于koa-multer
的相关API,其实基本上都是express-multer
来提供的,如下代码所示:
1 | let originalMulter = require('fix-esm').require('multer') |
🌠 这里我们看到koa-multer
基本上都没有实现自身的业务,它也就是简单地通过代理来执行对应函数而已,将any
、array
、fields
、none
、single
方法直接定义在创建出来的multer对象中,因为我们才可以直接通过multer.fields
等API方法的直接调用, 😕 而我们平时所使用的中间件是类似这样子的格式:(ctx, next) => {}
,因此通过这个makePromise()
函数来将原本的express
中间件给转换成koa
所能够识别的中间:
1 | function makePromise(multer, name){ |
从上面我们可以看出就是直接代理(通过Reflect.apply()
)的方式,来直接调用express-multer
中的相关API的,这里所涉及到的API都有:any
、array
、fields
、none
、single
😕 那么关于这个express-multer
的配置属性以及对应的API都 🈶 哪些呢?
express-multer相关API
express-multer
是一个用于处理multipart/form-data的node.js中间件,主要用于上传文件,只会处理包含multipart/form-data
的表单数据express-multer
将body对象和file或files对象添加到request对象,body对象包含表单文本字段的值,file或files对象包含通过表单上传的文件
请确保自行处理用户上传的文件,而不要将multer
作为全局的中间件,因为有可能恶意的用户会将文件上传到预想不到的路径中!!
相关配置参数
express-multer
接收一个options对象,该对象的属性描述如下所示:
属性 | 类型 | 默认值 | 描述 |
---|---|---|---|
dest | String | null | 该属性告诉multer将文件上传到哪个位置,如果忽略此选项对象,则文件将被保留在内存中,永远不会被写入到磁盘中 |
storage | String | DiskStorage|MemoryStorage | 磁盘缓存或内存缓存的对象 |
fileFilter | Function | 用以控制接收哪些文件的函数 | |
limits | Object | null | 用来限制上传的数据 |
preservePath | String | 保留文件的完整路径,而并非是基本的文件名称 |
Storage
上述属性中有一个storage
,可接收的属性值为DiskStorage
或者是MemoryStorage
,代表当使用内存控制时,可凭借MemoryStorage
来进行详细的控制,当使用磁盘缓存时,可凭借DiskStorage
来进行具体的控制!
DiskStorage
磁盘存储引擎可以让我们完全控制存储文件到磁盘的整个过程
1 | const storage = multer.diskStorage({ |
🌠 一般情况下,DiskStorage
接收两个选项destination
和filename
,destination
确定文件存储的路径,如果没有提供则用的系统默认的目录(这里需要注意的是目录需要提前创建好),而filename
则确定文件存储的名称,如果没有提供该属性则默认为每个文件赋予一个随机名称,该名称不包括扩展名,multer并不会为我们追加任何的文件扩展名,因此这个filename
应该返回一个完整的文件名和文件扩展名
MomoryStorage
内存存储引擎将文件作为
Buffer
对象存储在内存中,是multer
的默认选择
1 | const storage = multer.memoryStorage() |
对外暴露的API
- multer.single(fieldname): 接受名称为fieldname的单个文件,将存储单个文件在
req.file
属性中; - multer.array(fieldname[, maxCount]): 接受一个文件数组,所有的文件名称都是fieldname,如果出现错误,则可选上传的文件超过
maxCount
,上传的文件数组将存储在req.files
; - multer.fields(fields): 接受由
fields
指定的混合文件,具有文件数组的对象将存储在req.files
中,fields
是类似于{ name: 'avatar', maxCount: 1 }
这种格式的对象; - multer.none(): 仅接受文本字段,禁止上传文件;
- multer.any(): 接受所有通过网络传输的文件,文件数组将存储在
req.files
中
学到什么
有时可能没有现成的
koa
框架的中间件,但是可以借助于express
的中间件进行一个包装,转换为属于koa
的中间件来使用