一、需求

之前使用 express 的时候,使用 multer 进行文件上传,而 koa-multerkoa-modules 提供的文件上传中间件。

在 express 中使用 multer 进行文件上传:

两者使用起来其实本质上是一样的,提供的 API 也都差不多。

二、混淆点

其实文件上传使用最多的方面在 自定义文件上传路径自定义文件名称 上。

但是 express 使用的中间件方法模板是 (req,res,next)=>{},而 koa 的则是 ()=>{return async (ctx,next)=>{ }}

所以一开始的时候,我不是很明白如何无缝衔接或者更好的移植之前做好的一些模板。

在自定义文件上传路径和文件名方面,我看了一下 koa-multer 的接口,发现没什么大的变化,主要的接口是 diskStorage(用 typescript 实现的):

interface DiskStorageOptions {
        destination?: string | ((req: IncomingMessage, file: File, callback: (error: Error | null, destination: string) => void) => void);
        filename?(req: IncomingMessage, file: File, callback: (error: Error | null, filename: string) => void): void;
    }

可以发现,destination 其实还是字符串和 (req,file,callback)=>{} 两种形式,而 filename 也是一样。

三、实现

使用 multer 最显著的特点就是要通过 multer 生成 upload 中间件。

1、upload.js

借助 multer.diskStorage({}) 方法,实现自定义上传目录和文件名。

文件路径:./utils/upload.js

const multer = require('koa-multer');
const path = require('path');

const storage = multer.diskStorage({
  destination:'public/uploads/'+new Date().getFullYear() + (new Date().getMonth()+1) + new Date().getDate(),
  filename(ctx,file,cb){
    const filenameArr = file.originalname.split('.');
    cb(null,Date.now() + '.' + filenameArr[filenameArr.length-1]);
  }
});

const upload = multer({storage});

module.exports = upload;

2、在路由中使用 upload

导出 upload 之后,就可以在路由中使用 upload

router.get('upload',async (ctx) => {
  await ctx.render('upload');、);

router.post('upload',upload.single('file'),async (ctx) => {
  console.log(ctx.req.file);
  ctx.body = ctx.request.body;
});

同样的,upload 之后的文件信息,仍旧存储在 ctx.req.file 中,用来提供相关的信息。

filename 是存储的文件名称,而可以通过 destination 切割出文件的上传文件夹 201864path 没什么大的用处,因为 linux 上和 windows 是不同的,直接使用 path 不利于跨平台移植项目。

主要信息如下:

{ fieldname: 'file',
  originalname: '123123123123123.docx',
  encoding: '7bit',
  mimetype: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
  destination: 'public/uploads/201864',
  filename: '1528080376834.docx',
  path: 'public\\uploads\\201864\\1528080376834.docx',
  size: 17899 }

四、效果:

1.jpg

五、已知问题

koa-multerkoa-route 并不能完美的结合,因此不建议使用 koa-route,而是建议使用 koa-router (两者是不同的)。

毕竟 koa-route 都已经两年没更新了。

koa-router npm 地址: