createUploader
此函数用于文件上传,通过自定义配置创建一个上传器实例,并返回暂停、继续等回调函数
使用方式
js
import { createUploader } from 'enlarge-file-upload';
const config = {
....你的配置
}
const { upload, pause, resume, state } = createUploader(config);参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| config | Config | 是 | 上传器配置 |
返回值
| 参数名 | 类型 | 说明 |
|---|---|---|
| pause | () => void | 暂停上传 |
| resume | () => void | 继续上传 |
| upload | () => void | 开始上传 |
| state | State | 可用参数 |
ts 类型
ts
interface Uploader {
/**
* 启动文件上传
* @param file - 要上传的浏览器 File 对象
* @throws 分片初始化失败/上传过程中出现未处理错误
*/
upload: (file: File) => Promise<void>;
/**
* 暂停上传(会取消正在传输的请求)
*/
pause: () => void;
/**
* 恢复暂停的上传(从断点继续)
* @throws 未初始化分片时调用会报错
*/
resume: () => Promise<void>;
/**
* 重置所有状态到初始值(相当于重新初始化)
* - 清理所有分片数据
* - 取消所有进行中的请求
* - 清理定时器和缓存数据
* - 重置进度到 0%
*/
reset: () => void;
/**
* 实时状态对象,可通过监听相关属性实现响应式更新
*/
state: State;
}Config 配置
createMultiUploader的相关配置参数请一并参考此处说明
| 参数名 | 类型 | 必填 | 默认值 | 说明 | 支持版本 |
|---|---|---|---|---|---|
uploadFunction | Function | 是 | - | 上传函数,调用接口实现分片上传逻辑 | - |
chunkSize | Number | 否 | 5 * 1024 * 1024 | 单个切片大小(单位:字节),默认 5MB | - |
concurrency | Number | 否 | 5 | 并发上传数量 | - |
maxRetries | Number | 否 | 3 | 失败重试次数 | - |
startOffset | Number | 否 | 0 | 断点续传偏移量(从指定分片开始上传) | - |
enableLogging | Boolean | 否 | false | 是否开启日志记录,开启后会在控制台输出上传过程中的日志信息 | 2.4.2 |
logLevel | 'DEBUG' | 'INFO' | 'WARN' | 'ERROR' | 否 | 'INFO' | 日志级别,控制输出的最低日志级别,如参数为INFO,则仅输出INFO、WARN、ERROR级别的日志;如参数为DEBUG,则输出所有级别的日志。 | 2.4.2 |
consoleOutput | Boolean | 否 | true | 是否将日志输出到控制台,默认开启。如设置为false,则日志将仅通过 onLog 回调函数输出。 | 2.4.2 |
onLog | (log: Log) => void | 否 | - | 自定义日志回调函数,用于接收上传过程中的日志信息。参数 log 包含日志级别、消息内容和元数据。 | 2.4.2 |
includeChunks | Array<Number> | 否 | - | 指定需要上传的切片索引数组,默认上传所有切片 | - |
hash | Boolean | 否 | true | 是否计算文件整体哈希值 | - |
threads | number | 否 | 系统CPU核心数 - 2 | 计算 hash 所需要的 webworker 线程数 | - |
axiosInstance | AxiosInstance | 否 | - | 自定义 axios 实例,用于上传文件时的 HTTP 请求。一般不需要使用该属性,只有当提示axios获取为空或者需要自己接管axios时才使用 | 2.4.0 |
customHashApihashMode | 'crypto' | 'sha256' | 否 | 'crypto' | 自定义哈希计算 API,默认使用 Web Crypto API,也可以选择使用 sha256 算法 | 2.4.0 |
awaitHash | Boolean | 否 | true | 是否等待哈希计算完成(仅当hash:true时生效),大文件建议设为false | - |
chunkMap | Boolean | Object | 否 | false | 分片哈希计算配置:true-同步计算所有分片hash{indices:[], async:true}-async为true开启异步计算,indices为需要计算的分片索引数组,默认计算所有分片 | - |
customHash | Function | Object | 否 | - | 自定义哈希计算函数或配置对象,用于自定义计算文件哈希值。传入函数时,只在文件上传前调用一次,传入对象且 flow 为 true 时,则开启流式调用,每个分片上传前都会调用 | - |
onProgress | Function | 否 | - | 上传进度回调,参数为{percent, loaded, total} | - |
onSpeed | Function | 否 | - | 上传速度回调(单位:KB/s) | - |
onSuccess | Function | 否 | - | 上传成功回调 | - |
onError | Function | 否 | - | 上传失败回调 | - |
beginHash | Function | 否 | - | 开始计算哈希时的回调(仅当hash:true时触发) | - |
endHash | Function | 否 | - | 哈希计算完成时的回调(仅当hash:true时触发) | - |
onEta | Function | 否 | - | 上传剩余时间回调 | 2.4.3 |
配置示例
js
// 自定义上传函数
/**
* 分片上传处理函数系统入参解释
* @param {Object} options - 系统入参
* @param {Blob} options.chunk - 当前分片的二进制数据
* @param {number} options.index - 当前分片的索引
* @param {string} options.hash - 当前文件的哈希值(是当前文件hash,不是当前分片)
* @param {CancelToken} options.cancelToken - 取消令牌(用于取消上传)
*/
async function uploadFunction({ chunk, index, hash, cancelToken }) {
const formData = new FormData();
formData.append("chunk", chunk);
formData.append("hash", hash);
formData.append("index", index);
await axios.post("http://xxxx/api/upload", formData, {
cancelToken,
});
}
const config = {
chunkSize: 5 * 1024 * 1024, // 5MB分片
concurrency: 3, // 并发数3
maxRetries: 2, // 失败重试2次
hash: true, // 开启文件哈希计算
awaitHash: false, // 不等待哈希计算(大文件优化)
chunkMap: true, // 计算分片hash值
// axiosInstance: axios, // 你的axios实例。该属性只有在极少数情况下才会使用
enableLogging: true, // 开启日志记录
logLevel: 'INFO', // 日志级别,控制输出的最低日志级别
onLog: (log) => {
// 打印日志到控制台 (或者你可以发送到你的服务端)
console.log(`[${log.level}] ${log.message}`, log.metadata);
}
uploadFunction,
onProgress: (progress) => {
console.log(`进度: ${progress.percent}%`);
},
};ts 类型
ts
/**
* 自定义哈希计算的返回结果:
* - hash: 当前文件整体hash值(字符串)
* - hashMap: 一个 Map,用于存储每个分片的哈希值
*/
type HashResult = Promise<{
hash: string;
hashMap: Map<number, string>;
}>;
/**
* 流式计算模式:
* - 参数:
* - chunk: 当前分片的二进制数据
* - index: 当前分片的索引
* - 返回:
* - 一个 Promise,解析为 HashResult
*/
type ChunkHashFn = (chunk: Blob, index: number) => HashResult;
/**
* 单次计算模式:
* - 参数:
* - file: 完整文件对象
* - 返回:
* - 一个 Promise,解析为 HashResult
*/
type FileHashFn = (file: File) => HashResult;
/**
* 日志条目接口
*/
export interface LogEntry {
/**
* 日志时间戳 (ISO 8601格式)
*/
timestamp: string;
/**
* 会话ID,用于关联同一次上传的所有日志
*/
sessionId: string;
/**
* 日志级别
*/
level: 'DEBUG' | 'INFO' | 'WARN' | 'ERROR';
/**
* 日志消息
*/
message: string;
/**
* 日志元数据
*/
metadata?: Record<string, any>;
}
export interface Config {
/**
* 【必需】分片上传处理函数
* @example ({ chunk, index, hash }) => axios.post(uploadUrl, formData)
*/
uploadFunction: (options: UploadOptions) => Promise<void>;
/**
* 【可选】分片大小(字节),默认为 5MB
* @default 5 * 1024 * 1024
*/
chunkSize?: number;
/**
* 【可选】起始分片位置索引(用于断点续传),默认从第一个分片开始
* @example 3 (从第4个分片开始)
*/
startOffset?: number;
/**
* 【可选】指定要上传的分片索引数组(优先级高于 startOffset)
* @example [0,2,3] (仅上传索引为0、2、3的分片)
*/
includeChunks?: number[];
/**
* 【可选】上传失败时的最大重试次数,默认 3 次
* @default 3
*/
maxRetries?: number;
/**
* 【可选】最大并发请求数,默认 5
* @default 5
*/
concurrency?: number;
/**
* 【可选】是否计算文件哈希,默认 true 计算hash值
* @default true
*/
hash?: boolean;
/**
* 【可选】指定计算hash所需要的webworker线程数
* @default 系统CPU核心数 - 2
*/
threads?: number;
/**
* 【可选】自定义 axios 实例,用于上传文件时的 HTTP 请求
*/
axiosInstance?: AxiosInstance;
/**
* 【可选】是否等待哈希计算完成再上传,默认 true
* @default true
*/
awaitHash?: boolean;
/**
* 【可选】哈希计算模式,默认自动选择
* - 'crypto': 使用 Web Crypto API(性能更好,但大文件可能内存不足)
* - 'sha256': 使用自定义 sha256 实现(更稳定,支持超大文件)
* @default 自动选择:1GB以下文件使用 crypto,1GB以上使用 sha256
*/
hashMode?: "crypto" | "sha256";
/**
* @deprecated 请使用 hashMode 代替,此属性将在未来版本移除
*/
customHashApi?: "crypto" | "sha256";
/**
* 可选】自定义计算哈希函数:
* 支持两种模式:
* 1. 直接传入整体文件的哈希函数
* 2. 传入一个对象,启用 流式计算 模式:
* - flow: 是否启用分片流式处理(chunk)模式
* - calculationHash: 分片级哈希函数
*/
customHash?:
| FileHashFn
| {
flow: Boolean;
calculationHash: ChunkHashFn;
};
/**
* 【可选】是否计算所有切片hash,默认 false
* @default false
*/
chunkMap?: boolean | { async: boolean; indices?: number[] };
/**
* 【回调】开始计算哈希时触发
*/
beginHash?: () => void;
/**
* 【回调】哈希计算完成后触发,返回最终哈希值
*/
endHash?: (hash: string) => void;
/**
* 【回调】上传进度变化时触发,返回 0-100 的数值
*/
onProgress?: (progress: number) => void;
/**
* 【回调】实时上传速度变化时触发,返回带有单位的字符串
* @example "2.45 MB/s"
*/
onSpeed?: (speed: string) => void;
/**
* 【回调】预估剩余时间变化时触发,返回剩余秒数
* @example 120 (表示还剩约2分钟)
*/
onEta?: (eta: number) => void;
/**
* 【回调】全部分片上传完成且合并成功时触发
*/
onSuccess?: () => void;
/**
* 【回调】上传失败时触发,返回错误信息
*/
onError?: (error: any) => void;
/**
* 【可选】是否启用日志记录功能
* @default false
*/
enableLogging?: boolean;
/**
* 【可选】日志级别,控制输出的最低日志级别
* @default 'INFO'
*/
logLevel?: 'DEBUG' | 'INFO' | 'WARN' | 'ERROR';
/**
* 【可选】是否将日志输出到浏览器控制台
* @default true
*/
consoleOutput?: boolean;
/**
* 【回调】日志记录时触发,可用于自定义日志处理(如发送到服务端)
* @example (log) => { console.log(log); sendToServer(log); }
*/
onLog?: (log: LogEntry) => void;
}
interface UploadOptions {
/**
* 当前分片数据
* @example new Blob([file.slice(0, chunkSize)])
*/
chunk: Blob;
/**
* 当前分片索引(从0开始计数的绝对位置,包含起始偏移量)
* @example 如果设定 startOffset=3,则实际索引范围是 [3,4,5...]
*/
index: number;
/**
* 文件的唯一哈希值
* @example "sha256-xxxxxx"
*/
hash: string | null;
/**
* 用于取消请求的 axios 取消令牌
* @example axios.CancelToken.source().token
*/
cancelToken: CancelToken;
}State 属性
| 属性名 | 类型 | 说明 |
|---|---|---|
progress | number | 上传进度百分比 (0-100) |
speed | string | 实时上传速度(带单位),例如 "1.23 MB/s" |
uploadEnd | boolean | 是否已完成上传 |
hash | string | 文件哈希值(基于分片内容的 SHA256 计算) |
file | File | null | 当前上传的原始 File 对象 |
totalChunks | number | 总分片数(包含断点续传的偏移量分片) |
errorMsg | Error | null | 上传错误信息(失败时不为 null) |
allChunks | [] | 所有切片数组(存储分片数据) |
hashMap | Map<number, string> | 分片哈希映射表 (需开启计算才会生成,默认关闭) |
eta | number | 上传剩余时间 |
ts 类型
ts
interface State {
/**
* 上传进度百分比 (0-100)
*/
progress: number;
/**
* 当前实时上传速度(包含单位)
* @example "1.23 MB/s"
*/
speed: string;
/**
* 是否已完成上传
*/
uploadEnd: boolean;
/**
* 文件哈希值(基于分片内容的 SHA256)
*/
hash: string;
/**
* 当前上传的原始 File 对象
*/
file: File | null;
/**
* 总分片数(包含偏移量分片)
*/
totalChunks: number;
/**
* 上传错误信息
*/
errorMsg: Error | null;
/**
* 所有切片
*/
allChunks: [];
/**
* 所有切片hashMap(需要开启计算才有,默认不开启)
*/
hashMap: Map<number, string>;
/**
* 上传剩余时间
*/
eta: number;
}