腾讯云云开发云函数 之 文件导入功能

背景

Twikoo 评论系统要实现导入功能,导入,就需要上传文件。

通过调用云函数,我们能够传递 string、number 等简单的参数,想要上传文件?不太行。

想到云开发环境有一块默认开通的 COS 空间,这块空间允许登录用户上传文件,只要利用这片空间,就可以实现将文件上传给云函数的功能了。

主要思路

  1. 前端调用 js-sdk 上传文件,获取到 fileID
  2. 前端将 fileID 作为参数,调用云函数
  3. 云函数通过 fileID 获取到文件,并解析

前端上传

首先需要用户选择文件,先写一个选择文件的 input 和一个上传文件的 button。

vue template
1
2
<input type="file" value="" ref="inputFile" />
<button @click="uploadFile" :disabled="loading">开始导入</button>

再编写上传的方法。

vue script
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
// 获取用户选择的文件
const filePath = this.$refs.inputFile.files[0]
if (!filePath) {
alert('未选择文件')
return
}
try {
const result = await this.$tcb.app.uploadFile({
// 由于上传的文件是公有读的,所以并不安全
// 通过使用毫秒时间戳作为文件名,一定程度防止其他用户猜测并下载文件
// 适用于并发不大的场景
cloudPath: `import/${Date.now()}`,
filePath,
onUploadProgress: (progressEvent) => {
// 通过 SDK 可以获取到上传进度
const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total)
console.log(`已上传 ${percentCompleted}%`)
}
})
// 获得到上传的 fileID
console.log(`上传完成 ${result.fileID}`)
// 调用云函数,传递 fileID 给云函数,具体实现略
await importFile(result.fileID)
} catch (e) {
console.error(e)
}

这样一个上传功能就完成了。但我们还需要服务器获取到上传的文件,怎样获得呢?

云函数下载

云函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 通过接收到的 fileID 读取云存储中的文件
async function readFile (fileId, type, log) {
try {
const result = await app.downloadFile({ fileID: fileId })
console.log('文件下载成功')
const content = result.fileContent.toString('utf8')
console.log('文件读取成功')
// 删除读取完成的文件,保证不因为公有读而泄露
await app.deleteFile({ fileList: [fileId] })
return content
} catch (e) {
console.log(`评论文件读取失败:${e.message}`)
}
}

好了,云函数已经成功取得前端上传的文件内容了,接下来就可以实现导入逻辑了。

本文仅摘部分关键代码解读,完整代码可在 Twikoo 中参考

最终实现了下图所示的导入功能(故意上传了一个错误的文件)

腾讯云云开发云函数 之 文件导入功能

https://www.imaegoo.com/2020/tcb-functions-upload/

作者

iMaeGoo

发布于

2020-12-10

更新于

2020-12-10

许可协议

CC BY 4.0

评论