enlarge-file-upload
v1.0.28
Published
A tool for chunked file upload with concurrency control.
Downloads
116
Maintainers
Readme
File Upload Tool
请优先下载最新版本库 这是一个用于大文件上传的工具包,提供了系列函数用来支持暂停、恢复、上传进度等功能,内置了错误重传策略,支持断点续传、重传、重试等功能(此库上传基于 axios 库,如果项目不支持 axios,勿用...)。
安装
npm install enlarge-file-upload
参数介绍
/**
* descript 入参详解
* @param {Number} chunkSize? 文件单个切片大小,默认5MB
* @param {Number} concurrency? 并发上传数量,默认5
* @param {Number} maxRetries? 失败重试次数,默认3
* @param {Number} startOffset? 断点续传偏移量,默认0
* @param {Array} includeChunks? 需要上传的切片索引,默认上传所有切片
* 如果startOffset和includeChunks参数同时存在,且startOffset不为0,默认优先使用startOffset参数
* @param {Boolen} hash? 是否开启hash计算,默认开启,可选参数
* @param {Boolen} awaitHash? 是否等待hash值,默认等待,可选参数(仅在hash为true时生效)
* awaitHash参数,如果上传文件较小时可以开启等待;如果文件超大,建议关闭,大文件hash值计算时间较长,避免等待阻塞主线程
* @param {Function} uploadFunction 上传函数,必传参数
* @param {Function} onProgress? 上传进度回调函数,可选
* @param {Function} onSpeed? 上传速度回调函数,可选
* @param {Function} onSuccess? 上传成功后回调函数,可选
* @param {Function} beginHash? 开始计算Hash值回调函数,可选(只会在上传前调用一次,且hash.open必须true)
* @param {Function} endHash? Hash值计算完毕回调函数,可选(只会在上传前调用一次,且hash.open必须true)
*/
// 参数示例
const config = {
chunkSize: 5 * 1024 * 1024,
concurrency: 5,
maxRetries: 3,
startOffset:0,
includeChunks,
hash: false,
awaitHash: false,
uploadFunction,
onProgress,
onSuccess
onSpeed,
beginHash,
endHash
};
/**
* descript fileUploadTool方法返回一个对象,包含上传方法、暂停方法、继续方法等
* upload 上传方法
* pause 暂停方法
* resume 继续方法
* state 状态对象,包含上传进度、hash值、上传速度等
*/
// 方法调用
const { upload, pause, resume, state } = fileUploadTool(config);
案例
原生 js 中使用示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>文件上传</title>
</head>
<script src="https://cdn.jsdelivr.net/npm/enlarge-file-upload/dist/upload.min.js"></script>
<!-- 引入 Axios 库,用于发送 HTTP 请求 -->
<script src="https://cdn.bootcdn.net/ajax/libs/axios/1.5.0/axios.js"></script>
<body>
<input type="file" id="fileInput" />
<button id="pauseButton">暂停上传</button>
<button id="resumeButton">继续上传</button>
<div id="progress">上传进度:0%</div>
<div id="speed">上传速度:0 MB/s</div>
<script>
// 定义上传函数
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://localhost:3000/api/users", formData, {
cancelToken,
});
}
// 使用示例
const config = {
chunkSize: 5 * 1024 * 1024, // 5MB
concurrency: 5,
maxRetries: 3,
// startOffset: 6, // 从索引为10的切片位置开始传
// includeChunks:[1,6], // 只上传索引为1和6的切片,只有startOffset为0或空时才生效
uploadFunction,
onProgress: (progress) => {
document.getElementById(
"progress"
).innerText = `上传进度:${state.progress.toFixed(2)}%`;
},
onSuccess: () => {
console.log("上传完毕");
},
onSpeed: (speed) => {
document.getElementById("speed").innerText = `上传速度:${speed}`;
},
};
const { upload, pause, resume, state } = createUploader(config);
const fileInput = document.getElementById("fileInput");
fileInput.addEventListener("change", () => {
const file = fileInput.files[0];
upload(file);
});
// 暂停上传
document.getElementById("pauseButton").addEventListener("click", () => {
pause();
});
// 继续上传
document.getElementById("resumeButton").addEventListener("click", () => {
resume();
});
</script>
</body>
</html>
React 中使用示例
在 react 中,这里的 useMemo 是必须要使用的,避免组件渲染的时候,重新创建 uploader 对象。
import React, { useState, useMemo } from "react";
import createUploader from "enlarge-file-upload";
import type { Config, UploadOptions } from "enlarge-file-upload";
import axios from "axios";
const FileUpload = () => {
const [progress, setProgress] = useState(0);
const [speed, setSpeed] = useState("0 MB/s");
// 定义上传函数
async function uploadFunction({
chunk,
index,
hash,
cancelToken,
}: UploadOptions) {
const formData = new FormData();
formData.append("chunk", chunk);
formData.append("hash", hash);
formData.append("index", index);
await axios.post("http://localhost:3000/api/users", formData, {
cancelToken,
});
}
const uploaderConfig: Config = useMemo(
() => ({
chunkSize: 5 * 1024 * 1024, // 5MB
concurrency: 5,
maxRetries: 3,
// startOffset: 6, // 从索引为10的切片位置开始传
// includeChunks:[1,6], // 只上传索引为1和6的切片,只有startOffset为0或空时才生效
uploadFunction,
onProgress: (progress) => {
setProgress(progress);
},
onSuccess: () => {
console.log("上传完毕");
},
onSpeed: (speed) => {
setSpeed(speed);
},
}),
[]
);
const uploader = useMemo(
() => createUploader(uploaderConfig),
[uploaderConfig]
);
const handleFileChange = (event) => {
const file = event.target.files[0];
uploader?.upload(file);
};
const handlePause = () => {
uploader?.pause();
};
const handleResume = () => {
uploader?.resume();
};
return (
<div>
<input type="file" onChange={handleFileChange} />
<button onClick={handlePause}>暂停上传</button>
<button onClick={handleResume}>继续上传</button>
<div>上传进度:{progress.toFixed(2)}%</div>
<div>上传速度:{speed}</div>
</div>
);
};
export default FileUpload;
封装为 react Hooks
一个简单的封装,如有特殊需求,可以基于这个 hooks 进行修改
import { useState, useMemo, useCallback } from "react";
import createUploader from "enlarge-file-upload";
import type { Config, UploadOptions } from "enlarge-file-upload";
import axios from "axios";
const useFileUploader = () => {
const [progress, setProgress] = useState(0);
const [speed, setSpeed] = useState("0 MB/s");
const uploadFunction = useCallback(
async ({ chunk, index, hash, cancelToken }: UploadOptions) => {
const formData = new FormData();
formData.append("chunk", chunk);
formData.append("hash", hash);
formData.append("index", index);
await axios.post("http://localhost:3000/api/users", formData, {
cancelToken,
});
},
[]
);
const uploaderConfig: Config = useMemo(
() => ({
chunkSize: 5 * 1024 * 1024, // 5MB
concurrency: 5,
maxRetries: 3,
// startOffset: 6, // 从索引为10的切片位置开始传
// includeChunks:[1,6], // 只上传索引为1和6的切片,只有startOffset为0或空时才生效
uploadFunction,
onProgress: (progress) => {
setProgress(progress);
},
onSuccess: () => {
console.log("Upload complete");
},
onSpeed: (speed) => {
setSpeed(speed);
},
}),
[uploadFunction]
);
const uploader = useMemo(
() => createUploader(uploaderConfig),
[uploaderConfig]
);
const uploadFile = useCallback(
(file) => {
uploader?.upload(file);
},
[uploader]
);
const pauseUpload = useCallback(() => {
uploader?.pause();
}, [uploader]);
const resumeUpload = useCallback(() => {
uploader?.resume();
}, [uploader]);
return {
progress,
speed,
uploadFile,
pauseUpload,
resumeUpload,
};
};
export default useFileUploader;
使用封装好的 Hooks 示例
import React from "react";
import useFileUploader from "./useFileUploader.tsx";
const FileUpload = () => {
const { progress, speed, uploadFile, pauseUpload, resumeUpload } =
useFileUploader();
const handleFileChange = (event) => {
const file = event.target.files[0];
uploadFile(file);
};
return (
<div>
<input type="file" onChange={handleFileChange} />
<button onClick={pauseUpload}>Pause Upload</button>
<button onClick={resumeUpload}>Resume Upload</button>
<div>Upload Progress: {progress.toFixed(2)}%</div>
<div>Upload Speed: {speed}</div>
</div>
);
};
export default FileUpload;
建议
如果对此工具包有更好的建议或需要支持新的功能,欢迎提 issue 或者加本人的 QQ:1844119859。