js - H5 上传(FE 部分)
async function action(file) { const fileHash = await computedFileHash(file); const chunks = createChunks(file, { chunkSize: 1024 * 10, fileHash }); } /** * 文件切片群上传 * * @param {Object} chunks 文件切片群 */ function uploadChunks(chunks, maxRequest = 6) { return new Promise((resolve, reject) => { if (!chunks.length) resolve([]); let requestSliceArr = []; let start = 0; let index = 0; let requestResults = []; let requestErrResults = []; while(start < chunks.length) { const stop = start + maxRequest; requestSliceArr.push(chunks.slice(start, stop)); start = stop; } const request = async () => { if (index > requestSliceArr.length - 1) return resolve(requestResults); let sliceChunks = requestSliceArr[index++]; Promise.all(sliceChunks.map(chunk => uploadHandler(chunk))) .then(res => { requestResults.push(...(Array.isArray(res) ? res : [])); request(); // 循环调用 }) .catch((err) => { requestErrResults.push(...(Array.isArray(err) ? err : [])) reject(requestErrResults); }) } }) } /** * 单个文件切片上传逻辑 * * @param {Object} chunk 文件切片 */ function uploader(chunk, url) { return new Promise((resolve, reject) => { const fd = new FormData(); const { file, fileHash, chunkIndex } = chunk; fd.append('file', file); fd.append('fileHash', fileHash); fd,append('chunkIndex', chunkIndex); fetch(url, { method: 'POST', body: fd, }).then(res => { chunk.uploaded = true; resolve(res.json()); }).catch(err => reject(err)); }); } const defaultChunkOptions = { chunkSize: 1024 * 1024 * 1, } function createChunks(file, options = defaultChunkOptions) { const _opts = { ...defaultChunkOptions, ...options, }; const { chunkSize, fileHash } = _opts; const chunks = []; let start = index = 0; while (start < file.size) { const stop = start + chunkSize; const currentChunk = file.slice(start, stop); chunks.push({ file: currentChunk, uploaded: false, chunkIndex: index++, fileHash }); start = stop; } return chunks; } // -------------- utils -------------- function computedFileHash(file) { return new Promise((resolve) => { const fileReader = new FileReader(); fileReader.onload = e => { resolve(SparkMD5.ArrayBuffer.hash(e.target.result)); }; fileReader.readAsArrayBuffer(file); }) }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· 单线程的Redis速度为什么快?
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码