前话: 是否需要SDK
注意:
Qiniu JS SDK也提供了直传的api,安全性会高一些
- 如果上传的文件不大(自己根据业务情况界定), 可以选择直传
- 市面上的上传组件都有上传文件功能, 将其文件通过form-data格式上传
- 上传地址(七牛云地址)
-
uploadURL = 'https://up.qiniup.com'
;// 代表华东区域
-
uploadURL = 'https://up-z1.qiniup.com'
;// 代表华北区域
-
uploadURL = 'https://up-z2.qiniup.com'
;// 代表华南区域
-
uploadURL = 'https://up-as0.qiniup.com'
;// 代表东南亚区域
-
uploadURL = 'https://up-na0.qiniup.com'
;// 代表北美区域
-
- 参数
- 一个用于七牛云上传所需token(一般是后端给)。
- key, 唯一性强一点儿的(后端需要用这个获取文件)
代码例
const afterRead = async (event) => {
// 请求函数获取七牛云上传文件所需token 省略...
// 上传地址和token 后端一起返回给我的
const uploadFileParams = {
region, // 上传地址
token, // 上传所需token
fileType: 'image', // 上传文件类型
name: 'file', // 文件对应的 key
filePath: event.file.url, // 文件临时存储地址
}
const fileKey = await uploadFileTOQinIu(uploadFileParams) // fileKey 就是自己上传的key 这个key需要传递给后端 后端用于获取对应的上传文件
}
/**
* 上传文件到七牛云
* @param data.region {string} 七牛云存储区域
* @param data.token {string} 七牛云上传凭证
* @param data.filePath {string} 文件路径
* @param data.fileType {string} 文件类型
* @param data.name {string} 文件对应的 key
*/
function uploadFileTOQinIu (data) {
const { region, token, filePath, fileType, name } = data
const key = generateUniqueKey()
return new Promise((resolve, reject) => {
uni.uploadFile({
url: region,
filePath,
fileType,
name,
formData: {
key,
token
},
success: (uploadFileRes) => {
const key = JSON.parse(uploadFileRes.data).key;
resolve(key)
},
fail: (err) => {
reject(err)
}
});
})
}
function generateUniqueKey() {
const timestamp = Date.now(); // 当前时间戳
const randomNum = Math.floor(Math.random() * 1000000); // 生成六位随机数
return `${timestamp}_${randomNum}`;
}
1. 安装SDK
目前官网最新的版本为 qiniu@4.0.0-beta.6
npm i qiniu-js
pnpm add qiniu-js
2.导入SDK
在需要上传文件的地方导入即可
import { createDirectUploadTask, createMultipartUploadV2Task, FileData } from 'qiniu-js';
3.创建上传任务
// 创建上传数据
const fileData: FileData = { type: 'file', data: File}
const fileData: FileData = { type: 'string', data: 'content' }
const fileData: FileData = { type: 'array-buffer', data: new ArrayBuffer(1e3) }
// createDirectUploadTask 创建直传任务
const uploadTask = createDirectUploadTask(fileData, UploadConfig);
// 创建分片上传任务
// 部分私有云服务版本较老的请使用 v1 分片上传
const uploadTask = createMultipartUploadV2Task(fileData, UploadConfig);
4.UploadConfig
- 上传配置接口,用于配置上传任务的相关参数。
apiServerUrl
:服务的接口地址;默认为七牛公有云,示例:api.qiniu.com 该配置仅当未设置uploadHosts
时生效,SDK 将会通过指定的 api 服务提供的接口来动态获取上传地址,私有云请联系集群运维人员,并确认集群是否支持v4/query
接口uploadHosts
: 上传服务地址,手动指定上传服务地址,示例:up.qiniu.comlogLevel
:日志级别。protocol
:HTTP 协议,默认 HTTPS。tokenProvider
:用于获取上传所需 token 的函数。- 一个用于获取上传所需 token 的函数类型。
- 返回一个 Promise,该 Promise 提供上传所需的 token。
type TokenProvider = () => Promise<string>
vars
: 上传过程中的自定义变量。
interface UploadConfig {
tokenProvider: TokenProvider;
apiServerUrl?: string;
uploadHosts?: []string;
logLevel?: LogLevel;
protocol?: HttpProtocol;
vars?: Record<string, string>;
}
5. 启动任务
uploadTask.start()
6.设置进度回调函数
-
UploadTask
- 上传任务接口,用于控制上传任务的执行和处理回调函数。
onProgress(fn: OnProgress)
:设置进度回调函数。- 进度回调函数类型。
type OnProgress = (progress: Progress, context: Context) => void;
onComplete(fn: OnComplete)
:设置完成回调函数。- 完成回调函数类型。
- 接收一个上下文参数,并返回
void
。
type OnComplete = (result: string, context: Context) => void;
onError(fn: OnError)
:设置错误回调函数。- 错误回调函数类型。
type OnError = (error: UploadError, context: Context) => void;
cancel()
:取消上传任务,并返回一个 Promise,该 Promise 在解析时提供任务结果。start()
:启动上传任务,并返回一个 Promise, 该 Promise 在解析时提供任务结果。
-
Context
- 上传的上下文接口,用于存储任务相关的信息。
host
:上传使用的 host。token
:上传使用的 token。result
:上传成功的信息。error
:队列的错误。progress
:整体的任务进度信息。
// 设置进度回调函数
uploadTask.onProgress((progress, context) => {
// 处理进度回调
});
// 设置完成回调函数
uploadTask.onComplete((result, context) => {
// 处理完成回调
});
// 设置错误回调函数
uploadTask.onError((error, context) => {
// 处理错误回调
});
代码举例
vue3+vite+uni cli+uview-plus
const afterRead = async (event) => {
// 如下生成的key值用于重命名用户上传的文件名 为了防止用户上传同一个文件 (业务需求)
const newFile = renameFile(event.file.tempFile, `${generateUniqueKey()}`)
const authRes = await getQinIuUploadToken()
const { region, token } = authRes?.data || {} // 获取后端返回的七牛云的上传地址和上传文件所需的凭证
if(!region || !token) {
return uni.showToast({
title: authRes.msg || '请重试',
icon: 'none',
duration: 1500
})
}
const fileData = { type: 'file', data: newFile } // 上传数据
const uploadConfig = {
uploadHosts: [region], // 上传地址
tokenProvider: async () => token // 上传文件所需要的凭证
}
const uploadTask = createMultipartUploadV2Task(fileData, uploadConfig); // 创建分片任务
// 启动任务
uploadTask.start()
// 设置进度回调函数
uploadTask.onProgress((progress, context) => {
// 处理进度回调
const { percent } = progress // 当前上传文件的总进度
});
// 设置完成回调函数
uploadTask.onComplete((result, context) => {
trainingVideo.value.push(event.file) // 把文件存储在 上传组件中 我使用的是uview-plus组件库
videoKey.value = result?.key // 保存上传完成后的key 到时候需要传递给后端 后端需要这个key获取对应文件
});
// 设置错误回调函数
uploadTask.onError((error, context) => {
uni.showToast({
title: '请重新上传',
icon: 'none',
duration: 1500
})
});
}
/** 重命名文件 */
function renameFile(file, newFileName) {
return new File([file], newFileName, {
type: file.type,
lastModified: file.lastModified,
});
}
最后,如有错误,请指正
- 祝大家向上