nos-uploader
特性
- 前端分块直传 nos(串行)
- 大文件并行上传 & 断点续传,需要业务后端支持
useage
npm i @imllz/nos-uploader -S
API
构造函数 new NosUploader(options: object)
- @param [options.file]: File 必须的。文件对象
- @param [options.namespace]: String 可选的。用于将 md5 相同的文件做区分
- @param [options.chunkSize]: Number 分块大小,默认10M
- @param [options.retryCount]: Number 失败重试次数, 默认3次
- @param [options.init]: Function 必须的。获取 nos 上传的信息。直传需要返回 { bucketName, objectName, url, token }。对于非直传需返回, 需支持 check 功能,接口入参 { key },返回 { url }, url 存在则上传已完成。非 check 情况,入参 { objectName },返回 { bucketName, key, uploadId }
- @param [options.customUploadChunk]: Function 自定义的分块上传接口,仅用于并行上传。回调参数:{ blob, uploadId, bucketName, objectName, onProgress }。需返回 Promise,数据格式 { url },并且 promise 实例上提供 abort 方法。
- @param [options.onProgress]: Function 进度回调。回调参数:{ loaded, total, percent }
- @param [options.onSuccess]: Function 成功回调。回调参数:{ url: string }
- @param [options.onError]: Function 失败回调 error
Methods
- start(): void 开始上传
- abort(): void 取消上传
对接 UI 组件库
- 以 ant-design-vue upload 组件为例,axios 作为请求库。 antd upload 支持 customRequest 接口,自定义上传逻辑。
// 并行上传 & 断点续传
import axios from 'axios'
import NosUploader from '@imzll/nos-uploader'
// antd upload 组件自定义上传请求的工厂方法
export default function createCustomRequest () {
// upload 组件自定义上传请求,params 为 antd upload 组件上传时回调参数
return function (params) {
const { file, onProgress: onProgressOfAntd, onSuccess, onError } = params
const nosUploader = new NosUploader({
file,
async init () {
// Base.multipartInit 需要业务后端实现
const result = await Base.multipartInit({
objectName: file.name
})
const { bucketName, key, token, url, uploadId } = result
return { bucketName, objectName: key, token, url, uploadId }
},
// 自定义并行上传分块的方法,回调参数如下
customUploadChunk ({ blob, uploadId, chunkNumber, bucketName, objectName, chunkSize, chunkCount, onProgress }) {
const source = CancelToken.source()
const formData = new FormData()
formData.append('key', objectName)
formData.append('uploadId', uploadId)
formData.append('partSize', chunkSize)
formData.append('partCount', chunkCount)
formData.append('partNumber', chunkNumber)
formData.append('blob', blob)
// Base.multipartUpload 需要业务后端实现
let promise = Base.multipartUpload(formData, {
cancelToken: source.token,
onUploadProgress: onProgress
}).then(res => {
if (!res.completeResult) return Promise.reject(new Error('分块上传失败'))
return res
})
// promise 需要提供 abort 取消当次上传的方法
promise.abort = function () {
source.cancel('upload chunck canceled')
}
return promise
},
// 总进度回调
onProgress ({ loaded, total, percent }) {
// 触发 antd 进度回调
onProgressOfAntd({ loaded, total, percent })
},
// 成功回调 { url, file, ... }
onSuccess (res) {
// 触发 antd 成功回调
onSuccess(res.url)
},
// 失败回调
// 触发 antd 失败回调
onError
})
// 开始上传
nosUploader.start()
// 这里需要返回一个对象给 antd 组件的,必须要有 abort 方法,供组件销毁时调用
return {
abort () {
nosUploader.abort()
}
}
}
}
// 前端直传,串行
import axios from 'axios'
import NosUploader from '@imzll/nos-uploader'
// antd upload 组件自定义上传请求的工厂方法
export default function createCustomRequest () {
// upload 组件自定义上传请求,params 为 antd upload 组件回调参数
return function (params) {
const { file, onProgress: onProgressOfAntd, onSuccess, onError } = params
const nosUploader = new NosUploader({
file,
async init () {
// Base.getToken 需要业务后端提供
const result = await Base.getToken({
fileNames: [params.file.name]
})
const { bucketName, objectName, token, objectUrl } = result[0]
return {
bucketName,
objectName,
token,
url: objectUrl
}
},
// 总进度回调
onProgress ({ loaded, total, percent }) {
// 触发 antd 进度回调
onProgressOfAntd({ loaded, total, percent })
},
// 成功回调 { url, file, ... }
onSuccess (res) {
// 触发 antd 成功回调
onSuccess(res.url)
},
// 触发 antd 失败回调
onError
})
// 开始上传
nosUploader.start()
// 这里需要返回一个对象给 antd 组件的,必须要有 abort 方法,供组件销毁时调用
return {
abort () {
nosUploader.abort()
}
}
}
}