【大前端】 断点续传 + 分片上传(大文件上传优化) 的前端示例

写一个 断点续传 + 分片上传(大文件上传优化) 的前端示例。

这样即使网络中断,文件也可以从已上传的部分继续传,不需要重新传整个大文件。


🔹 分片上传 + 断点续传思路

  1. 分片切割:把大文件切成固定大小的小块(chunk),例如 5MB/片。

  2. 生成唯一标识:用文件名 + 文件大小 + hash(可选,md5/sha1)来标识文件,保证续传时能识别已上传的部分。

  3. 秒传校验:上传前先请求后端,确认哪些分片已存在,只上传缺失的分片。

  4. 分片上传:前端逐个上传分片。

  5. 合并分片:上传完成后通知后端合并成一个完整文件。


🔹 原生 JS 分片上传 Demo

<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>分片上传 + 断点续传 Demo</title>
</head>
<body><h3>分片上传 + 断点续传</h3><input type="file" id="fileInput" /><button onclick="uploadFile()">上传</button><div id="log"></div><script>const CHUNK_SIZE = 5 * 1024 * 1024; // 每片 5MBasync function uploadFile() {const input = document.getElementById("fileInput");const file = input.files[0];if (!file) {alert("请选择文件");return;}const fileHash = await getFileHash(file); // 用于断点续传的唯一标识log(`文件哈希: ${fileHash}`);// 1. 向后端查询已上传的分片const uploadedChunks = await fetch(`http://localhost:8081/upload/check?fileHash=${fileHash}`).then(res => res.json()).catch(() => []);log(`已上传分片: ${uploadedChunks}`);// 2. 切割文件const chunks = [];let current = 0;let index = 0;while (current < file.size) {chunks.push({index,blob: file.slice(current, current + CHUNK_SIZE),});current += CHUNK_SIZE;index++;}// 3. 逐个上传分片(跳过已上传的)for (let chunk of chunks) {if (uploadedChunks.includes(chunk.index)) {log(`分片 ${chunk.index} 已存在,跳过`);continue;}await uploadChunk(fileHash, chunk);}// 4. 通知后端合并分片await fetch("http://localhost:8081/upload/merge", {method: "POST",headers: { "Content-Type": "application/json" },body: JSON.stringify({ fileHash, filename: file.name, totalChunks: chunks.length })});log("✅ 上传完成,已请求后端合并分片");}function uploadChunk(fileHash, chunk) {return new Promise((resolve, reject) => {const formData = new FormData();formData.append("file", chunk.blob);formData.append("fileHash", fileHash);formData.append("chunkIndex", chunk.index);const xhr = new XMLHttpRequest();xhr.open("POST", "http://localhost:8081/upload/chunk");xhr.upload.onprogress = (e) => {if (e.lengthComputable) {const percent = ((e.loaded / e.total) * 100).toFixed(2);log(`分片 ${chunk.index} 上传进度: ${percent}%`);}};xhr.onload = () => {if (xhr.status === 200) {log(`分片 ${chunk.index} 上传完成`);resolve();} else {reject(`分片 ${chunk.index} 上传失败`);}};xhr.onerror = () => reject(`分片 ${chunk.index} 上传错误`);xhr.send(formData);});}function getFileHash(file) {return new Promise((resolve) => {const reader = new FileReader();reader.onload = (e) => {// 简单 hash(真实场景可以用 SparkMD5)let hash = 0, data = new Uint8Array(e.target.result);for (let i = 0; i < data.length; i++) {hash = (hash + data[i]) % 99999999;}resolve(file.name + "-" + file.size + "-" + hash);};reader.readAsArrayBuffer(file.slice(0, 2 * 1024 * 1024)); // 只取前 2MB 计算 hash});}function log(msg) {document.getElementById("log").innerHTML += msg + "<br/>";}</script>
</body>
</html>

🔹 React 版(分片上传 + 断点续传)

如果需要 React 版本,可以用 axios 并结合 onUploadProgress,同时维护分片上传队列。


🔹 后端接口约定(以 Spring Boot 为例)

  1. 检查已上传分片
    GET /upload/check?fileHash=xxx
    返回已上传的分片索引数组 [0,2,5]

  2. 上传分片
    POST /upload/chunk

    • 参数:fileHashchunkIndexfile

  3. 合并分片
    POST /upload/merge

    • 参数:fileHashfilenametotalChunks


详细讲 分片上传的原理,从概念到流程再到优势和注意点,一看就懂。

🔹 分片上传原理


1️⃣ 分片上传是什么?

分片上传(Chunk Upload / Slice Upload)
将一个大文件拆分成若干小块(chunk),逐块上传到服务器,最后由服务器合并成完整文件。

为什么要分片?

  • 避免一次性上传大文件导致网络中断、浏览器崩溃或服务器压力过大。

  • 可以实现 断点续传:上传中断后只需要重新上传未完成的分片,而不是整个文件。

  • 支持大文件上传(几百 MB、几 GB 文件)。


2️⃣ 分片上传的基本原理

分片上传的原理可以分成几个步骤:

Step 1:文件切片

  • 将大文件按照固定大小(比如 5MB/片)切成多片。

  • 每片分配一个 索引(chunkIndex),用于后续识别和合并。

  • 可以生成一个 文件唯一标识(fileHash / fileId)

    • 常用方式:文件名 + 文件大小 + hash(前几 MB)

    • 用于判断文件是否已经上传过(秒传)或断点续传。

Step 2:上传分片

  • 每片单独上传到服务器。

  • 请求携带:

    • 分片内容 (file / chunk)

    • 文件标识 (fileHash)

    • 分片索引 (chunkIndex)

  • 服务器收到分片后可以保存到临时目录,例如 uploads/{fileHash}/{chunkIndex}

Step 3:断点续传

  • 上传前,客户端可以请求服务器:已上传了哪些分片。

  • 客户端只上传未完成的分片,提高效率。

  • 文件标识和分片索引是判断是否已经上传的关键。

Step 4:合并分片

  • 当所有分片上传完成后,客户端通知服务器合并。

  • 服务器按分片索引顺序,将所有分片写入到最终文件。

  • 完成后可以删除临时分片,释放存储空间。


3️⃣ 分片上传流程图

客户端:
[大文件] --> [分片切割] --> [分片上传1] --> [分片上传2] ... --> [分片上传N] --> [通知合并]服务器:
[接收分片] --> [保存到临时目录]
[合并分片] --> [生成完整文件]

4️⃣ 优势

  1. 支持大文件上传:避免一次性请求超时。

  2. 断点续传:网络中断可继续上传未完成的分片。

  3. 可并发上传:多个分片可同时上传,提高速度。

  4. 灵活性高:可实现秒传(判断文件是否已经上传过)或分布式存储(每片可存不同服务器)。


5️⃣ 注意点

  • 分片大小选择

    • 太小:分片数量多,请求开销大。

    • 太大:网络中断时重传成本高。

    • 常用:2~10MB/片。

  • 文件标识生成

    • 需保证唯一性和稳定性。

    • 常用 hash + 文件名 + 大小组合。

  • 分片索引

    • 上传和合并时一定要按顺序,否则合并文件可能出错。

  • 服务器存储

    • 临时存储分片,合并完成后删除,避免磁盘堆积。

  • 安全性

    • 限制上传文件类型和大小。

    • 对文件名和路径做严格校验,防止目录遍历攻击。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/96103.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/96103.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习的发展与应用:从理论到现实

目录 引言 一、机器学习的发展历程 1. 萌芽阶段&#xff08;1950s–1970s&#xff09; 2. 符号主义与统计学习阶段&#xff08;1980s–1990s&#xff09; 3. 数据驱动与算法突破&#xff08;2000s–2010s&#xff09; 4. 深度学习崛起&#xff08;2012年至今&#xff09; …

Python实现讯飞星火大模型Spark4.0Ultra的WebSocket交互详解

核心架构设计与初始化机制 代码采用面向对象的设计模式构建了Ws_Param类作为核心配置载体。该类在初始化时接收四个关键参数:APPID(应用标识)、APIKey(接口密钥)、APISecret(签名秘钥)和Spark_url(服务端点地址)。通过urlparse模块解析URL结构,分离出主机名(host)与…

如何通过Linux在高通跃龙QCS6490 平台上优化部署AI/ML模型?

简介 高通于今年推出了高通跃龙&#xff0c;在边缘提供前沿的AI性能和超低延迟&#xff0c;为可扩展的工业创新带来新的可能性。研华已在各种规格尺寸的嵌入式方案中采用跃龙技术&#xff0c;包括由高通跃龙 QCS6490处理器支持的嵌入式模块、单板电脑和AI摄像头解决方案。研华…

MySQL内核革新:智能拦截全表扫描,百度智能云守护数据库性能与安全

在日常数据库运维中&#xff0c;“扫表风暴”数次悄然而至——某条未走索引的 SQL 突然执行全表扫描&#xff0c;短短几分钟内吃光 IO、拖高 CPU&#xff0c;最终引发集群抖动甚至服务不可用。这样的事故&#xff0c;你是否也曾经历过&#xff1f; 全表扫描&#xff08;Full Ta…

TCP 三次握手、四次挥手

三次握手 三次握手形象版&#xff0c;快速理解 deepseek 的象形比喻&#xff1a;三次握手建立连接就像打电话一样&#xff1a; (1) A 打给 B&#xff0c;“喂&#xff0c; 你能听到我说话吗&#xff1f;” (2) B 回答 A&#xff0c;“嗯&#xff0c;可以听到&#xff0c;你能听…

数据管理战略|1概念及组成部分

【小语】前面两个文章讲到了“数据管理战略数字化转型、数据驱动”三者之间关系,数字化改革中的原则与逻辑,本节用三次文章学习数据管理战略内容的组成部分(DAMA数据管理第1章1.2.6节)。 数据战略 VS 数字化转型 VS 数据驱动 数据管理战略|熵减与熵增相容原则 下文为【…

3.远程控制网络编程的设计上

RemoteCtrl.cpp// RemoteCtrl.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 //#include "pch.h" #include "framework.h" #include "RemoteCtrl.h"#ifdef _DEBUG #define new DEBUG_NEW #endif// 唯一的应用程序对象C…

毕业设计|基于Python的课程智能问答系统

4系统设计4.1功能模块设计对本系统进行全面的系统功能的分析&#xff0c;可以得出基于Python《Python程序设计》课程智能问答系统的功能模块图&#xff0c;如图4-1所示。图4-1 系统功能模块图4.2数据库设计4.2.1数据库设计原则学习程序设计时&#xff0c;若想要深入理解数据库管…

iOS原生开发和Flutter开发的看法

这是一个技术选型的问题。作为一名同时精通iOS原生和Flutter的开发者&#xff0c;我的看法是&#xff1a;这不是一个“二选一”的问题&#xff0c;而是一个“如何根据场景做最佳选择”的问题。 它们不是替代关系&#xff0c;而是互补关系。以下是我对两者的对比和看法&#xff…

docker桌面版 镜像配置

配置内容 Docker Engine配置*&#xff08;截止2025年09月10日能用&#xff09; {"builder": {"gc": {"defaultKeepStorage": "20GB","enabled": true}},"experimental": false,"registry-mirrors": [&q…

Java 面向对象基础初步

Java 面向对象基础初步 面向对象的核心概念概览 面向对象的核心目标是 把数据和操作封装在一起&#xff08;对象&#xff09;&#xff0c;并通过抽象、继承与多态组织程序。简而言之&#xff0c;我们总是没法回避程序设计的四个话题&#xff1a; 封装&#xff08;Encapsulation…

反向代理技术

一、核心比喻&#xff1a;公司的总机前台 想象一下一家大公司&#xff1a; 客户&#xff1a;想联系公司里的某位员工&#xff08;比如技术部的张三&#xff09;。公司的总机号码&#xff08;唯一公开的号码&#xff09;&#xff1a;比如 400-123-4567。前台&#xff1a;接听总机…

数据整理器(Data Collators)(90)

数据整理器(Data Collators) 数据整理器(Data Collators) 导致问题的“罪魁祸首”,往往是长度不一的序列。 指令格式 关键术语说明 数据整理器(Data Collators) 数据整理器负责将多个数据样本拼接成一个迷你批次(mini-batch)。它通常处于“隐形”状态——每次使用PyT…

PySpark EDA 完整案例介绍,附代码(三)

本篇文章Why Most Data Scientists Are Wrong About PySpark EDA — And How to Do It Right适合希望高效处理大数据的从业者。文章的亮点在于强调了使用PySpark进行探索性数据分析&#xff08;EDA&#xff09;的重要性&#xff0c;避免了将Spark数据框转换为Pandas的低效做法。…

leetcode18(无重复字符的最长子串)

给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长 子串 的长度。示例 1:输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc"&#xff0c;所以其长度为 3。思路&#xff1a;对于长度为0的数组单独处理其他数组最小的可能…

计算机毕设 java 高校家教平台 基于 SSM 框架的高校家教服务平台 Java+MySQL 的家教预约与课程管理系统

计算机毕设java高校家教平台75snd9 &#xff08;配套有源码 程序 mysql数据库 论文&#xff09;本套源码可以先看具体功能演示视频领取&#xff0c;文末有联xi 可分享在高校家教需求增长的背景下&#xff0c;传统家教对接依赖线下中介、信息分散&#xff0c;存在沟通成本高、课…

【自记】Python 的 SQLAlchemy 完整实践教程

目录 SQLAlchemy 介绍环境准备与安装数据库连接数据模型定义基本数据操作复杂查询操作高级特性实战项目示例性能优化与最佳实践常见问题与解决方案 1. SQLAlchemy 介绍 1.1 什么是SQLAlchemy SQLAlchemy 是一个用于 Python 的 SQL 工具和对象关系映射&#xff08;ORM&#x…

springboot rabbitmq 延时队列消息确认收货订单已完成

供应商后台-点击发货-默认3天自动收货确认&#xff0c;更新订单状态已完成。1 pom.xml 引入依赖&#xff1a;<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency>2 …

Linux内核TCP输出引擎:深入解析数据传输的核心机制

引言 传输控制协议(TCP)作为互联网最重要的基础协议之一,其实现质量直接关系到网络性能和应用体验。在Linux内核中,TCP协议的输出引擎是实现可靠数据传输的核心组件,负责将应用层数据高效、可靠地传输到网络对端。本文将深入分析Linux内核中TCP输出引擎的关键机制和实现原…

数据仓库详解

数据仓库详解第一节 数据仓库构建方法论和实践一、数据仓库与数据库的区别二、数据仓库对于企业的价值三、数据仓库的模型构建1、数据仓库构建需要考虑的问题2、什么是数仓的数据模型3、如何构建数仓的数据模型&#xff08;1&#xff09;概念模型设计&#xff08;2&#xff09;…