文件上传中间件: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的中间件来使用