展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 编程开发 > FastAPI和Vue实现文件分片上传+秒传+断点续传的完整思路

FastAPI和Vue实现文件分片上传+秒传+断点续传的完整思路

基于FastAPI与Vue3实现大文件分片上传,通过MD5哈希实现秒传与断点续传。后端提供检查、上传、合并三接口,前端使用SparkMD5计算文件指纹,控制并发上传。合并时需按索引顺序写入,分片大小建议5MB,注意浏览器并发限制。

本文目录

    你是不是也遇到过,上传个几百M的安装包或者设计稿,眼瞅着进度条走到99%,然后……网络波动一下,啪,没了!又要从头再来?这种崩溃的感觉,恐怕不少人都深有体会。

    FastAPI和Vue实现文件分片上传+秒传+断点续传的完整思路

    最近刚好在捣鼓文件上传的小工具,又把这块硬骨头啃了一遍。今天不聊虚的,就把这次用 FastAPI 和 Vue 实现大文件分片上传的完整思路,以及踩过的坑,都倒出来给大家参考。

    核心摘要:读完你能带走什么?

    这篇文章不会扔一堆晦涩的概念就跑。会像讲故事一样,把下面这些事讲明白:

    分片上传到底是怎么一回事儿,原理是啥。

    秒传和断点续传的核心逻辑(其实就隔一层窗户纸)。

    一份可以直接复制粘贴拿去用的 FastAPI 后端核心代码。

    一份 Vue3 前端的实现思路和关键代码片段。

    主要内容脉络

    1️⃣ 从一次抓狂的上传失败说起

    2️⃣ 别再盯着进度条了:聊聊分片、哈希与秒传

    3️⃣ 后端实战:FastAPI如何像收快递一样收文件

    4️⃣ 前端实战:Vue里那把切文件的“菜刀”

    5️⃣ 跑起来!以及那些年踩过的坑

    6️⃣ 结尾碎碎念

    1️⃣ 从一次抓狂的上传失败说起

    手机上传一段视频到电脑,“每次到一半就挂”。一查日志,413 Request Entity Too Large,Nginx和FastAPI双双拦截。

    调整配置大小限制?那是治标不治本,大文件上传慢、易失败是HTTP协议天生的短板。

    这就是为啥需要分片上传。

    思路特简单:把大象放进冰箱要几步?不对,是把大文件切成小块,一块块传,最后在服务端拼起来。

    2️⃣ 别再盯着进度条了:聊聊分片、哈希与秒传

    好,先来理顺几个核心概念,别急着写代码。

    文件切片(Blob.slice)

    浏览器里,可以用 file.slice() 方法,像切西瓜一样把一个 File 对象切成一个个 Blob。比如设定每片5MB,一个100MB的文件就变成了20个小块。

    文件哈希(Spark-MD5)

    接下来重点来了!文件指纹,也就是MD5值。 这东西是文件的唯一身份证号。你可能会问,为啥要算这个?

    一是为了秒传:后端一看,“哟,这个MD5我数据库里有啊,文件存着呢!” 直接告诉你“传完了”,用户体验瞬间起飞。

    二是为了校验:确保服务端拼起来的文件没缺胳膊少腿。

    这里千万别学当初有人偷懒,想着用 文件名+修改时间 来当唯一标识,结果用户把文件重命名一下,或者换个文件夹上传,后端就傻傻地又存了一份一模一样的垃圾数据。

    断点续传

    原理就是每次上传前,先拿MD5去问后端:“我这文件,哪些片你已经有了?”

    后端返回一个数组,比如 [0, 1, 3] ,意思就是第0、1、3片传过了。前端直接跳过这些片,从第2片开始传。

    是不是以为这样就完了?对,核心就这么简单!

    3️⃣ 后端实战:FastAPI如何像收快递一样收文件

    后端用的是 Python 界的当红炸子鸡 FastAPI,它处理文件上传异步非阻塞,性能杠杠的。

    检查分片接口(实现秒传+断点续传)

    @app.post("/upload/check")
    async def check_chunks(file_hash: str, total_chunks: int):
        # 1. 去数据库查这个hash
        file_record = await db.get_file_by_hash(file_hash)
        if file_record:
            # 如果存在完整文件记录,直接返回秒传信号
            return {"status": "success", "code": 200, "data": {"uploaded": True}}
        # 2. 不存在,就去磁盘找临时分片文件夹
        temp_dir = Path(f"temp/{file_hash}")
        uploaded_chunks = []
        if temp_dir.exists():
            for chunk_file in temp_dir.iterdir():
                # 文件名约定为 chunk_index
                uploaded_chunks.append(int(chunk_file.stem))
        return {"status": "success", "data": {"uploaded": False, "uploaded_chunks": uploaded_chunks}}
    

    再说个容易翻车的点: 临时文件夹的路径设计。

    千万别把所有分片都扔一个文件夹里,文件多了系统查找速度会变慢。按 file_hash 的前两位或者直接建一个同名文件夹,是最稳妥的做法。

    上传分片接口

    @app.post("/upload/chunk")
    async def upload_chunk(
        file: UploadFile = File(...),
        file_hash: str = Form(...),
        chunk_index: int = Form(...),
    ):
        temp_dir = Path(f"temp/{file_hash}")
        temp_dir.mkdir(exist_ok=True)
        chunk_path = temp_dir / str(chunk_index)
        # 把上传的分片内容异步写入磁盘
        with open(chunk_path, "wb") as f:
            while content := await file.read(1024 * 1024): # 1MB一读
                f.write(content)
        return {"status": "success", "chunk_index": chunk_index}
    

    合并分片接口

    @app.post("/upload/merge")
    async def merge_chunks(file_hash: str, file_name: str, total_chunks: int):
        temp_dir = Path(f"temp/{file_hash}")
        target_path = Path(f"uploads/{file_hash}_{file_name}")
        # 注意:要按照分片索引顺序写入!
        with open(target_path, "wb") as target_f:
            for i in range(total_chunks):
                chunk_path = temp_dir / str(i)
                with open(chunk_path, "rb") as chunk_f:
                    target_f.write(chunk_f.read())
        # 清理临时分片和文件夹(这里可以用 shutil.rmtree)
        # 校验MD5是否一致...
        # 写入数据库记录...
        return {"status": "success", "code": 200}
    

    4️⃣ 前端实战:Vue里那把切文件的“菜刀”

    前端用的是 Vue3 + Element Plus ,核心库是 spark-md5 。

    第一步:切肉,不对,切文件并计算Hash

    计算大文件的MD5是个CPU密集型任务,如果直接卡在主线程,页面会直接假死。

    官方文档虽然建议用 Worker,但根据实际经验,不用 Worker 而是用 requestIdleCallback 或者分片读取计算,对小几G的文件来说,体验也是OK的,代码还少。

    // 伪代码示例,思路最重要
    const CHUNK_SIZE = 5 * 1024 * 1024; // 5MB一片
    async function handleUpload(file) {
      const chunks = createChunks(file);
      // 计算Hash (这里略去具体SparkMD5的增量计算代码,否则太长了)
      const fileHash = await computeHash(chunks);
      // 1. 检查是否秒传或需要断点续传
      const { uploaded, uploadedChunks } = await checkChunksApi(fileHash, chunks.length);
      if (uploaded) {
        ElMessage.success('文件秒传成功!');
        return;
      }
      // 2. 过滤出未上传的分片
      const pendingChunks = chunks.filter((_, index) => !uploadedChunks.includes(index));
      // 3. 并发上传 (千万别同时全发出去,要控制并发数,比如一次最多6个)
      await uploadChunksWithPool(pendingChunks, fileHash, 6);
      // 4. 通知后端合并
      await mergeChunksApi(fileHash, file.name, chunks.length);
      ElMessage.success('总算传完了,合并成功!');
    }
    

    这个工具的选择,好比选螺丝刀,不是最贵的最好,而是最顺手的。这里用 spark-md5 完全够用,别为了高大上去引入一整套 crypto-js,太重了。

    5️⃣ 跑起来!以及那些年踩过的坑

    ⚠️ 坑一:分片大小怎么定?

    别设太小,比如100KB,那样请求数爆炸,浏览器并发扛不住,后端压力也大。也别太大,失去断点续传的意义。个人经验,5MB 或 10MB 是个很舒服的区间。

    ⚠️ 坑二:合并文件时的顺序!

    后端合并分片时,千万注意要按照 chunk_index 从小到大写入。如果用了 os.listdir() 然后直接遍历,系统返回的顺序可能是乱的,拼出来的文件就坏了。有人就这样坏过一个3个G的模型包,血泪教训啊!

    ⚠️ 坑三:并发上传控制

    浏览器对同一域名的并发连接数是有限制的(HTTP/1.1一般是6个)。如果 for 循环里直接发几百个请求,后面的请求全得排队,甚至直接失败。一定要写个简单的请求池,控制同时在传的分片数。

    结尾碎碎念

    大文件上传这玩意儿,看着唬人,其实拆解开来就三件事:切、传、合。核心难点都在异常处理和细节的打磨上。希望这份分享,能让你在实现这个功能时,少熬几个大夜,少掉几根头发。

    如果你在实际操作中遇到了什么妖魔鬼怪的问题,或者有更好的实现思路,欢迎随时留言交流。技术在交流中才会变得更有趣嘛。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 FastAPI
    相关文章 更多
    精品专题 更多
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    IOS软件

    正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

    AI

    正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

    Mac软件 更多
    Aperty macOS版
    Aperty macOS版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw macOS版
    AionClaw macOS版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy macOS版
    Loomy macOS版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirBuddy 3 macOS版
    AirBuddy 3 macOS版

    AirBuddy 3 是面向 macOS 的蓝牙外设增强工具,可集中查看 AirPods、Beats 与苹果设备电量,提供快速连接、播放控制、电量提醒、桌面小组件和多台 Mac 外设接力等功能。

    AirServer macOS版
    AirServer macOS版

    AirServer macOS版可把 Mac 转换为无线投屏接收端,通过 AirPlay 或 Google Cast 接收手机、平板和电脑画面,并支持多设备同时连接、高清镜像及会话录制,适合家庭娱乐、课堂教学、会议演示和应用展示。

    AnyDesk macOS版
    AnyDesk macOS版

    AnyDesk macOS版是一款适用于远程办公、设备维护和客户支持的远程桌面工具,可连接并操作异地计算机,支持文件传输、无人值守访问、会话权限控制及跨平台协作。

    WINDOWS 更多
    讯飞绘文 网页版
    讯飞绘文 网页版

    讯飞绘文网页版是科大讯飞推出的AI图文创作与内容运营工具,覆盖热点选题、文章生成、稿件校对、智能配图、排版发布和数据复盘等环节,适合自媒体创作者及内容团队在线使用。

    Maya(Autodesk Maya) Windows版
    Maya(Autodesk Maya) Windows版

    Autodesk Maya 是面向影视、电视、动画和游戏行业的专业三维制作软件,集多边形与 NURBS 建模、角色绑定、关键帧和动作捕捉动画、Bifrost 特效模拟、材质开发及 Arnold 渲染于一体,

    Aperty Windows版
    Aperty Windows版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw Windows版
    AionClaw Windows版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy Windows版
    Loomy Windows版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirServer Windows版
    AirServer Windows版

    AirServer Windows版可把电脑变成AirPlay、Google Cast和Miracast无线投屏接收端,适合会议演示、课堂教学及家庭大屏分享。发送设备通常无需另装客户端,并可同时接收和智能排列多个镜像会话。