2019-04-08 | koa2 | UNLOCK

重拾koa2之文件上传

busboy模块

busboy模块是用来解析POST请求的,Node原生req中的文件流,官方文档:https://github.com/mscdex/busboy
例子代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
const Koa = require('koa2')
const path = require('path')
const app = new Koa()
//const bodyParser = require('koa-bodyparser)

const{ uploadFile } = require('./busboy.js')

//app.use(bodyParser())

app.use(async (ctx)=>{

if(ctx.url === '/' && ctx.method === 'GET'){
//当GET请求时候返回表单页面
let html = `
<h1>koa2 upload demo</h1>
<form method="POST" action="/upload.json" enctype="multipart/form-data">
<p>file upload</p>
<span>picName:</span><input name="picName" type="text" /><br/>
<input name="file" type="file" /><br/><br/>
<button type="submit">submit</button>
</form>
`
ctx.body = html
}else if(ctx.url === '/upload.json'&& ctx.method === 'POST'){
//上传文件请求处理
let result = {success:false}
let serverFilePath = path.join(__dirname,'uplaod-files')

//上传文件事件
result = await uploadFile(ctx,{
fileType:'album',
path:serverFilePath
})

ctx.body = result
}else{
//其他请求显示404
ctx.body = '404'
}

})

app.listen(3000,()=>{
console.log('busboy is running ')
})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
const inspect = require('util').inspect
const path = require('path')
const os = require('os')
const fs = require('fs')
const Busboy = require('busboy')

// 同步创建文件目录
function mkdirsSync(dirname) {
if (fs.existsSync(dirname)) {
return true
} else {
if (mkdirsSync(path.dirname(dirname))) {
fs.mkdirSync(dirname)
return true
}
}
}

// 获取上传文件的后缀名
function getSuffixNmae(fileName) {
let nameList = fileName.split('.')
return nameList[nameList.length - 1]
}

// 上传文件
function uploadFile(ctx, option) {
let req = ctx.req
let res = ctx.res
let busboy = new Busboy({ headers: req.headers })

//获取类型
let fileType = option.fileType || 'common'
let filePath = path.join(option.path, fileType)
let mkdirResult = mkdirsSync(filePath)

return new Promise((resolve, reject) => {
console.log('文件上传中...')
let result = {
success: false,
formData: {},
}

//解析请求文件事件
busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
let fileName = Math.random().toString(16).substr(2) + '.' + getSuffixNmae(filename)
let _uploadFilePath = path.join(filePath,fileName)
let saveTo = path.join(_uploadFilePath)

//文件保存到指定路径
file.pipe(fs.createWriteStream(saveTo))

file.on('data',function(data){
console.log(`File [${fileName}] got ${data.length} bytes`)

})
//文件写入事件结束
file.on('end', function () {
result.success = true
result.message = '文件上传成功!'
resolve(result)
})
})

//解析表单中其他字段信息
busboy.on('field',function(fieldname,val,fieldnameTruncated,valTruncated,encoding,mimetype){
console.log('表单字段数据['+fieldname+']:value'+inspect(val))
result.formData[fieldname] = inspect(val)
})

//解析结束事件
busboy.on('finish',function(){
console.log('文件结束')
resolve(result)
})

//解析错误事件
busboy.on('error',function(err){
console.log('文件上出错')
reject(result)
})

req.pipe(busboy)
})
}

module.exports= {
uploadFile
}

koa-multer

koa-body

未完待续……….

评论加载中