使用titbit开发Web后端服务03:处理上传的文件

上传文件

默认会解析上传的文件,你可以在初始化服务的时候,传递parseBody选项关闭它,关于选项后面有详细的说明。
解析后的文件数据在c.files中存储,具体结构请往下看。

 1 'use strict'
 2 
 3 const titbit = require('titbit')
 4 
 5 const app = new titbit()
 6 
 7 app.post('/upload', async c => {
 8   //解析后的文件在c.files中存储,通过getFile可以方便获取文件数据。
 9   let imgfile = c.getFile('image')
10   if (!imgfile) {
11     c.res.body = 'file not found'
12     return
13   } else if (imgfile.data.length > 2000000) {
14     c.res.body = 'max file size: 2M'
15     return
16   }
17  
18   //此函数是助手函数,makeName默认会按照时间戳生成名字,extName解析文件的扩展名。
19   //但这可以有更简单的形式,请看下行代码。
20   //let fname = `${c.helper.makeName()}${c.helper.extName(imgfile.filename)}`
21 
22   //根据原始文件名解析扩展名并生成时间戳加随机数的唯一文件名。
23   let fname = c.helper.makeName(imgfile.filename)
24 
25   try {
26     c.res.body = await c.moveFile(imgfile, fname)
27   } catch (err) {
28     c.res.body = err.message
29   }
30  
31 });
32 
33 app.run(1234)

c.files数据结构

这种结构是根据HTTP协议上传文件时的数据构造设计的,HTTP协议允许同一个上传名有多个文件,所以要解析成一个数组。而使用getFile默认情况只返回第一个文件,因为多数情况只是一个上传名对应一个文件。

 

对于前端来说,上传名就是你在HTML中表单的name属性:<input type="file" name="image"> 。image是上传名,不要把上传名和文件名混淆。

 1 {
 2   "image" : [
 3     {
 4       'content-type': CONTENT_TYPE,
 5       filename: ORIGIN_FILENAME,
 6       start : START,
 7       end   : END,
 8       length: LENGTH
 9     },
10     ...
11   ],
12 
13   "video" : [
14     {
15       'content-type': CONTENT_TYPE,  //文件类型
16       filename: ORIGIN_FILENAME //原始文件名
17       start : START, //ctx.rawBody开始的索引位置
18       end   : END,   //ctx.rawBody结束的索引位置
19       length: LENGTH,  //文件长度,字节数
20     },
21     ...
22   ]
23 }


c.getFile就是通过名称索引,默认索引值是0,如果是一个小于0的数字,则会获取整个文件数组,没有返回null。

titbit-toolkit扩展是一个组件集合,其中的tofile扩展可以给每个获取的file对象添加toFile方法用于快速保存文件:

 1 const {tofile} = require('titbit-toolkit')
 2 const titbit = require('titbit')
 3 
 4 const app = new titbit({
 5   debug: true
 6 })
 7 
 8 let tf = new tofile()
 9 
10 //启用中间件,mid函数用于返回中间件函数
11 app.use( tf.mid() )
12 
13 app.post('/upload', async c => {
14     let f = c.getFile('image')
15 
16     if (f === null) {
17         c.status(400)
18         return
19     }
20 
21     //把文件移动到images目录,此目录可能需要手动创建。
22     //可以使用第二个参数指定文件名,默认会根据时间戳和随机数生成唯一文件名。
23     let fname = await f.toFile('./images')
24 
25     //返回上传的文件名
26     c.res.body = fname
27 
28 })
29 
30 app.run(1234)

 

源代码地址:

gitee(码云)

github

安装

npm install titbit

posted @ 2020-12-25 05:57  简单的机械键盘  阅读(97)  评论(0)    收藏  举报