大文件上传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…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
论文笔记——相干体技术在裂缝预测中的应用研究
目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !
我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...
