大文件上传demo,前端基于Uppy,后端基于koa
前言
文件上传基本上所有的管理系统之类的项目都有这么一个功能。因为使用了Element,可以方便的使用
其提供的Upload组件,对于普通上传来说基本上就够用了。但是有时候会涉及到大文件上传的需求,这时就会面临一些问题:比如文件上传超时。
自己做的话很麻烦,需要考虑到的东西非常多。这时可以考虑使用第三方封装的库。这里推荐Uppy ,主要是这个库一直在维护,有些库都是几年前的了,比如WebUploader。
只是简单的研究,遇到问题,看官方文档
官方文档: https://uppy.io/docs/quick-start/
官方git: https://github.com/transloadit/uppy
准备工作
前端基于vue3,后端基于koa。(主业前端,后端是业余爱好只是简单了解)
前端
项目创建具体见:使用Vite搭建Vue3 + Ts项目,这里就不介绍了。
搭建完项目需要安装一下:axios 、element-plus ,运行项目后如下图:

后端
项目创建具体见:Koa学习1:初始化项目
运行项目后如下图:

整合
现在处理一下,让vue前端能够请求到数据
后端
需要安装koa2-cors来解决跨域问题
npm install koa2-cors
修改后的main.js
// 导入Koa
const Koa = require("koa");
// 用于解决跨域
const cors = require("koa2-cors");
// 实例化
const app = new Koa();app.use(cors());// 中间件
app.use(async (ctx, next) => {const start = Date.now();await next();ctx.body = "hellow koa";
});// 监听端口
app.listen(5000, () => {console.log(`app listening at http://localhost:5000`);
});
前端
修改vite.config.ts配置文件
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';// https://vitejs.dev/config/
export default defineConfig({plugins: [vue()],server: {proxy: {'/api': {target: 'http://localhost:5000/',changeOrigin: true,rewrite: path => path.replace(/^\/api/, '')}}}
});
修改App.vue
<template><div class="upload-container"><el-button type="primary" ="getData">上传</el-button><p>数据是:{{ message }}</p></div>
</template><script setup lang="ts">
import { ref } from 'vue';
import axios from 'axios';const message = ref('');// 请求数据
const getData = () => {axios.get('http://localhost:5000/').then(res => {message.value = res.dataconsole.log("数据是:", res.data)})
}</script><style scoped>
.upload-container {display: flex;justify-content: center;align-items: center;height: 700px;
}
</style>
效果图

简单demo,上传图片
前端
安装uppy
npm install /core /drag-drop /status-bar /xhr-upload
core核心包drag-drop用于实现拖拽上传status-bar显示上传进度条xhr-upload实现文件上传
<template><div class="upload-container"><div id="drag-drop-area"><!-- 默认样式,也可以在里面进行自定义 --></div><div id="status-bar"></div></div>
</template><script setup lang="ts">
import { ref, onMounted } from "vue"
import { ElMessage } from 'element-plus'import Uppy from '@uppy/core';
import DragDrop from '@uppy/drag-drop';
import StatusBar from '@uppy/status-bar';
import XHRUpload from '@uppy/xhr-upload';//引入样式
import '@uppy/core/dist/style.min.css';
import '@uppy/drag-drop/dist/style.min.css';// 1mb大小
const ONE_MB = 1024 * 1024;const uppy = ref()onMounted(() => {uppy.value = new Uppy({debug: true, // 允许拖拽autoProceed: false, // 是否自动上传restrictions: {maxFileSize: 10 * ONE_MB, // 设置最大文件大小maxNumberOfFiles: 5, // 设置最大上传文件数量allowedFileTypes: ['.jpg', '.jpeg', '.png'] // 设置允许的文件类型}}).use(DragDrop, { target: '#drag-drop-area', note: '拖放或点击' }) // 启用拖动.use(StatusBar, { target: '#status-bar' }) //启用进度条.use(XHRUpload, {endpoint: 'http://localhost:5000/upload', // 设置上传文件的API接口formData: true // 启用FormData发送数据});// 监听文件上传uppy.value.on('upload-success', (file: any, response: any) => {// console.log("上传的文件:", file)console.log("返回的信息:", response)if (response.body.code == 0) {ElMessage.success(`文件${file.name}上传成功`)} else {ElMessage.error(`文件${file.name}上传失败,${response.body.message}`)}})
})</script><style scoped>
.upload-container {display: flex;justify-content: center;align-items: center;height: 700px;
}
</style>
后端
安装koa-body中间件,它可以方便地处理请求体中的文件数据。
npm install koa-body
安装koa-router中间件,用于post请求
npm install koa-router
修改main.js
// 导入Koa
const Koa = require("koa");
// 用于解决跨域
const cors = require("koa2-cors");
// 用于文件上传
const { koaBody } = require("koa-body");
// 用于处理路径
const path = require("path");
// 引入路由
const Router = require("koa-router");// 注意如果有改动,则要重启一下。如果觉得麻烦可以设置热重启,具体见:https://blog.csdn.net/weixin_41897680/article/details/130907232// 实例化
const app = new Koa();
const router = new Router();app.use(cors());// 配置文件上传
app.use(koaBody({multipart: true, // 允许多文件formidable: {uploadDir: path.join(__dirname, "uploads"), // 设置文件上传目录,必须有这个文件夹不然会报错keepExtensions: true, // 保持文件扩展名},})
);router.get("/", async (ctx) => {ctx.body = "hello Koa";
});// 文件上传
router.post("/upload", async (ctx) => {// 获取上传的文件try {const file = await ctx.request.files.file;console.log("文件信息:", file);ctx.body = {message: "文件上传成功",data: {size: file.size, //文件大小fileName: file.originalFilename, // 文件的原始名称filePath: file.filepath, // 在服务器上的保存路径updateTime: file.lastModifiedDate, // 上次修改的时间},};} catch (err) {ctx.body = {message: err,data: {},};}
});//挂载路由
app.use(router.routes()).use(router.allowedMethods());// 监听端口
app.listen(5000, () => {console.log(`app listening at http://localhost:5000`);
});


大文件上传、断点续传
实现分片上传并且支持断点续传需要基于Tus
Tus 是一种开放协议,用于基于 HTTP 构建的可恢复上传。这意味着 意外关闭选项卡或失去连接,让您继续,对于 实例,您的 10GB 上传,而不是重新开始。
Tus 支持任何语言、任何平台和任何网络。它需要一个客户端 和服务器集成工作。您可以签出客户端和服务器实现,以查找首选语言的服务器。
前端
前端变化不大,Uppy为我们提供了对应的插件,修改后的代码如下:
<!-- 大文件上传 -->
<template><div class="upload-container"><div id="drag-drop-area"><!-- 默认样式,也可以在里面进行自定义 --></div><div id="status-bar"></div><br /><el-button type="primary" ="pauseOrResume">{{ isUploadding ? '暂停' : '开始' }}</el-button></div>
</template><script setup lang="ts">
import { ref, onMounted } from "vue"
import { ElMessage } from 'element-plus'import Uppy from '@uppy/core';
import DragDrop from '@uppy/drag-drop';
import StatusBar from '@uppy/status-bar';
import Tus from '@uppy/tus';//引入样式
import '@uppy/core/dist/style.min.css';
import '@uppy/drag-drop/dist/style.min.css';// 1mb大小
const ONE_MB = 1024 * 1024;
// 是否正在上传,默认在上传
const isUploadding = ref(true)let uppy: Uppy;onMounted(() => {uppy = new Uppy({debug: true, // 允许拖拽autoProceed: false, // 是否自动上传restrictions: {maxFileSize: 300 * ONE_MB, // 设置最大文件大小maxNumberOfFiles: 5, // 设置最大上传文件数量allowedFileTypes: ['.jpg', '.jpeg', '.png', '.zip'] // 设置允许的文件类型},}).use(DragDrop, { target: '#drag-drop-area', note: '拖放或点击' }) // 启用拖动.use(StatusBar, { target: '#status-bar' }) //启用进度条.use(Tus, {endpoint: 'http://127.0.0.1:5000/files', // 设置上传文件的API接口limit: 5, // 限制同时进行的上传数量,默认值20,不要没有限制或者过大chunkSize: 5 * ONE_MB // 设置分片的大小});// 监听文件上传uppy.on('complete', (result: any) => {// result是一个对象,属性是:// 会返回failed(Array),因为可以多文件上传会返回一个数组// successful(Array),因为可以多文件上传会返回一个数组,包含文件上传成功的信息console.log("上传完成:",result)if (Array.isArray(result.failed) && result.failed.length>0) {ElMessage.error(`文件上传失败,${result.failed}`)} else {ElMessage.success(`文件上传成功`)}})
})// 暂停与恢复
const pauseOrResume = () => {if (isUploadding.value) {// 正在上传uppy.pauseAll()} else {// 暂停中uppy.resumeAll()}isUploadding.value = !isUploadding.value
}</script><style scoped>
.upload-container {width: 300px;margin: 100px auto;height: 700px;
}
</style>
后端
后端变化挺大的,你需要将你的服务器变得支持Tus,刚好官方提供了对应的插件(Java后台、php后台可以自行百度如何集成)
插件官方文档
https://github.com/tus/tus-node-server
官方集成案例,这个很重要,会介绍插件的属性、事件等
https://github.com/tus/tus-node-server/tree/main/packages/server
安装
npm i /file-store /server tus-node-server
代码
const Koa = require("koa");
const { Server } = require("@tus/server");
const { FileStore } = require("@tus/file-store");
// 用于解决跨域
const cors = require("koa2-cors");const host = "127.0.0.1";
const port = 5000;
// 创建一个tusServer服务
const tusServer = new Server({path: "/files", // 路由datastore: new FileStore({ directory: "./files" }), // 文件存储的位置
});const app = new Koa();app.use(cors());// 将 tus-server 添加为 Koa 的中间件
app.use(async (ctx, next) => {// 注:tus-server 的处理程序要求精确匹配路由路径,这里无法使用koa-router。只能当作一个单独的中间件使用await tusServer.handle.bind(tusServer)(ctx.req, ctx.res);
});// 注:tus-server 的处理程序要求精确匹配路由路径,这里无法使用koa-router。只能当作一个单独的中间件使用app.listen(port, host, () => {console.log(`Server is running on http://${host}:${port}`);
});
执行效果

上传完成后会生成两个文件,如下:
第一个就是上传的文件,会变成一个二进制文件
第二个是这个文件的一下信息

前端Uppy库也会返回文件信息,如下图:

代码
代码放到码云上了,感兴趣的可以自己看一下
前端
地址
https://gitee.com/idonotyou/vue-upload
运行
npm i
npm run dev
后端
地址
https://gitee.com/idonotyou/koa-upload
运行
npm i
npm run dev
相关文章:
大文件上传demo,前端基于Uppy,后端基于koa
前言 文件上传基本上所有的管理系统之类的项目都有这么一个功能。因为使用了Element,可以方便的使用 其提供的Upload组件,对于普通上传来说基本上就够用了。但是有时候会涉及到大文件上传的需求,这时就会面临一些问题:比如文件上…...
typeScript--[函数定义]
一.TypesScript 函数的定义 函数的定义包括两种类型:函数声明和函数表达式。 1.函数声明 function hello(): string {return "hello" } 2.函数表达式 var hello1 function (): string {return "hello" } 二.函数之可选参数 参数后面的限…...
Spring初始化项目
1、官网用法 访问地址:https://start.spring.io idea配置:https://start.spring.io 2、阿里巴巴加速 访问地址:https://start.aliyun.com/bootstrap.html idea配置:https://start.aliyun.com 3、区别 官网阿里巴巴版本最新稍…...
Opencv 图像金字塔----高斯和拉普拉斯
原文:图像金字塔----高斯和拉普拉斯 图像金字塔是图像中多尺度表达的一种,最初用于机器视觉和图像压缩,最主要用于图像的分割、融合。 高斯金字塔 ( Gaussian pyramid): 高斯金字塔是由底部的最大分辨率图像逐次向下采样得到的一系列图像…...
gitLab(git)误提交命令
1.先使用下面命令查看一下分支上已提交的信息 git log 2.回退到之前的版本 git reset —hard 你要删除的提交哈希码(一般是离这个命令最近的一串数字) 3.覆盖掉远端的版本信息,使远端的仓库也回退到相应的版本 注意:切换到你提…...
Rust个人学习笔记2
一定要牢记Rust是基于表达式的语言,除了声明语句和表达式语句外,其他的都是表达式。所以if也是表达式,它可以被用作右值。 条件控制 if-else。cpp和python得结合。 fn main() {let number 34;if number < 0 {println!("number &l…...
深入浅出Android同步屏障机制
原文链接 Android Sync Barrier机制 诡异的假死问题 前段时间,项目上遇到了一个假死问题,随机出现,无固定复现规律,大量频繁随机操作后,便会出现假死,整个应用无法操作,不会响应事件ÿ…...
工程管理系统简介 工程管理系统源码 java工程管理系统 工程管理系统功能设计
鸿鹄工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离构建工程项目管理系统 1. 项目背景 一、随着公司的快速发展,企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性,公司对内部工程管…...
Python 专栏目录索引
文章目录 Python 环境搭建Python 语法 变量、print、注释和运算符Python 的基本结构Python 中的文件和文件夹操作Python 中常用库Python 常见问题及解决方案Python 应用实例 Python 环境搭建 vscode搭建Python环境 Python 语法 变量、print、注释和运算符 python语法 变量、…...
SSM学习
技术架构 crm的技术架构: 视图层(view):展示数据,跟用户交互。 html, css,js,jquery,bootstrap(ext / easyUI),jsp控制层(Controller):控制业客处理流程(接收请求,接收参数,封装参数;根据不同的请求调用业务 (servlet, ) springMVC ( , webwork,strutsl,struts2)业…...
.net项目部署Docker
1、项目生成的bin目录下创建Dockerfile文件 #运行环境描述,此处是用的Net5构建镜像 FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build #复制文件到 docker容器中的app文件夹中 COPY . /app #设置工作目录为 app 文件夹,要和上面一致哦 WORKDIR /app #设…...
Ubuntu无法加载exfat的USB存储设备
当接入设备USB存储设备提示: 不能挂在63GB 卷 Error mounting /dev/sdb1 at /media/ubuntu/83C9-26F4: Command-line mount -t "exfat" -o "uhelperudisks2,nodev,nosuid,uid1000,gid1000,iocharsetutf8,namecase0,errorsremount-ro,umask0077"…...
【计算机网络】网络编程接口 Socket API 解读(2)
Socket 是网络协议栈暴露给编程人员的 API,相比复杂的计算机网络协议,API 对关键操作和配置数据进行了抽象,简化了程序编程。 本文讲述的 socket 内容源自 Linux 发行版 centos 9 上的 man 工具,和其他平台(比如 os-x …...
【黄啊码】PHP如何防止重复提交
防抖(Debounce)是一种防止重复提交的策略,它通过延迟一定时间来合并连续的操作,以确保只执行一次。 以下是几种防抖的实现方法以及对应的代码示例: 1. 前端 JavaScript 实现: 在前端使用 JavaScript 实现…...
2594. 修车的最少时间
文章目录 Tag题目来源题目解读解题思路方法一:二分枚举答案 写在最后 Tag 【二分枚举答案】【数组】 题目来源 2594. 修车的最少时间 题目解读 给你一个表示机械工能力的数组 ranks,ranks[i] 表示第 i 位机械工可以在 r a n k s [ i ] ∗ n 2 ranks[…...
vue 使用qrcode生成二维码并可下载保存
安装qrcode npm install qrcode --save代码 <template><div style"display: flex; flex-direction: column; align-items: center; justify-content center;"><div>查看溯源码,<a id"saveLink" style"text-decorati…...
网络融合的发展思路
虽然移动和固定网的融合代表了下一代网络的发展方向,但是目前移动和固定网的 发展还是独立的,有着各自的演进方式,要实现两个网络的完全融合是一个长期 的、逐步发展的过程。 网络融合的体系结构首先应坚持网络分层和功能分离的原则&#…...
报考浙江工业大学MBA项目如何选择合适的辅导班?
浙江工业大学MBA项目每年有数百人报考,在浙江省内除了浙大以外算是人数比较多的一个项目。2023级的招生中第一志愿也通过复试刷掉了百来人,在省内其实作为第一志愿报考的风险在逐渐增大,考生们如果坚持报考,则在针对联考初试的备考…...
算法训练第五十八天
总结:今日事单调栈的开端,还是挺巧妙的。 496. 下一个更大元素 I - 力扣(LeetCode) 代码: class Solution { public:vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& …...
如何快速生成一个H5滑动的卡片(单页和分页都有)
单页 <ul class"combo"><li v-for"(item, index) in arr" :key"index"><div class"combo-name">{{ item.A }}</div><div class"combo-price">{{ item.B }}</div><div class"co…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
LabVIEW双光子成像系统技术
双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...
c# 局部函数 定义、功能与示例
C# 局部函数:定义、功能与示例 1. 定义与功能 局部函数(Local Function)是嵌套在另一个方法内部的私有方法,仅在包含它的方法内可见。 • 作用:封装仅用于当前方法的逻辑,避免污染类作用域,提升…...
React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构
React 实战项目:微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇!在前 29 篇文章中,我们从 React 的基础概念逐步深入到高级技巧,涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...
电脑桌面太单调,用Python写一个桌面小宠物应用。
下面是一个使用Python创建的简单桌面小宠物应用。这个小宠物会在桌面上游荡,可以响应鼠标点击,并且有简单的动画效果。 import tkinter as tk import random import time from PIL import Image, ImageTk import os import sysclass DesktopPet:def __i…...
GraphRAG优化新思路-开源的ROGRAG框架
目前的如微软开源的GraphRAG的工作流程都较为复杂,难以孤立地评估各个组件的贡献,传统的检索方法在处理复杂推理任务时可能不够有效,特别是在需要理解实体间关系或多跳知识的情况下。先说结论,看完后感觉这个框架性能上不会比Grap…...
