大文件上传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

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

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

相关文章

stable diffusion实践操作-批次出图

系列文章目录 stable diffusion实践操作 文章目录 系列文章目录前言一、批次出图介绍1.1 webUI设置1.2 参数介绍 二、批次出图使用2.1 如何设置2.1 效果展示 总结 前言 本章主要介绍SD批次出图。 想要一次产生多张图片的时候使用。 一、批次出图介绍 1.1 webUI设置 1.2 参数…

IP应用场景查询API:深入了解网络用户行为的利器

前言 随着数字时代的不断发展&#xff0c;互联网已经成为人们生活的重要组成部分。而随着越来越多的业务和社交活动迁移到在线平台上&#xff0c;了解和理解网络用户行为变得至关重要。为了满足这个需求&#xff0c;IP 应用场景查询 API 崭露头角&#xff0c;成为深入了解网络…

RabbitMQ: return机制

1. Return机制 Confirm只能保证消息到达exchange&#xff0c;无法保证消息可以被exchange分发到指定queue。 而且exchange是不能持久化消息的&#xff0c;queue是可以持久化消息。 采用Return机制来监听消息是否从exchange送到了指定的queue中 2.Java的实现方式 1.导入依赖 &l…

SQL函数

函数 字符串函数数值函数日期函数流程函数 字符串函数 常用函数&#xff1a; 函数功能CONCAT(s1, s2, …, sn)字符串拼接&#xff0c;将s1, s2, …, sn拼接成一个字符串LOWER(str)将字符串全部转为小写UPPER(str)将字符串全部转为大写LPAD(str, n, pad)左填充&#xff0c;用…

git ------ IDEA中建立本地/远程仓库及上传

目录 建立本地仓库 1. idea中选择创建本地仓库 选择目标文件 创建远程仓库 1.码云上进行库创建 将本地仓库数据提交到远程仓库 提交代码 推送到远程 建立本地仓库 1. idea中选择创建本地仓库 或 vsm中找下列2 即可 选择目标文件 成功后会出现以下标识 更新 提交 推…

盖子的c++小课堂——第二十二讲:2维dp

前言 大家好&#xff0c;我又来更新了&#xff0c;今天终于有时间了aaaaaaaa 破500粉了&#xff0c;我太高兴了哈哈哈哈哈哈&#xff08;别看IP地址&#xff0c;我去北京旅游回来了&#xff0c;他没改回来&#xff09;&#xff0c;然后我马上就成为创作者一年了&#xff0c;希…

Gitea--私有git服务器搭建详细教程

一.官方文档 https://docs.gitea.com/zh-cn/说明 gitea 是一个自己托管的Git服务程序。他和GitHub, Gitlab等比较类似。他是从 Gogs 发展而来&#xff0c;gitea的创作团队重新fork了代码&#xff0c;并命名为giteagitea 功能特性多&#xff0c;能够满足我们所有的的代码管理需…

Java基于 SpringBoot 的车辆充电桩系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W,Csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 文章目录 1、效果演示效果图技术栈 2、 前言介绍&#xff08;完整源码请私聊&#xff09;3、主要技术3.4.1 …

C语言文本为什么不包括库函数和预处理命令

C语言的文本不包括库函数和预处理命令 是因为库函数和预处理命令并不是C语言本身的一部分&#xff0c; 它们是由C语言标准库和预处理器提供的功能。 C语言标准库是一组预定义的函数和常量&#xff0c; 用于提供常见的功能&#xff0c;如输入输出、字符串处理、数学计算等。 …

国密SSL证书是什么?cfca的证书靠谱吗

2019年&#xff0c;《中华人民共和国密码法》第三章表明&#xff1a;“国家鼓励在外商投资过程中基于自愿原则和商业规则开展商用密码技术合作。” 2020年&#xff0c;《中华人民共和国密码法》正式施行&#xff0c; 标志着国家在提升密码工作的科学化、规范化、法治化水平&am…

TLA+学习记录1——hello world

0x01 TLA是个好工具 编程人员一个好习惯是凡事都想偷懒&#xff0c;当然是指要科学地偷懒&#xff0c;而不是真的偷懒。一直想找到一种能检验写出的代码&#xff0c;做出的设计是否真的完全正确&#xff0c;而不是靠经验检视、代码Review、反复测试去检验。因为上述方法不管怎…

End-to-End Object Detection with Transformers(论文解析)

End-to-End Object Detection with Transformers 摘要介绍相关工作2.1 集合预测2.2 transformer和并行解码2.3 目标检测 3 DETR模型3.1 目标检测集设置预测损失3.2 DETR架构 摘要 我们提出了一种将目标检测视为直接集合预测问题的新方法。我们的方法简化了检测流程&#xff0c…

借助AI分析哥斯拉木马原理与Tomcat回显链路挖掘

前言 本次分析使用了ChatGPT进行辅助分析&#xff0c;大大提升了工作效率&#xff0c;很快就分析出木马的工作流程和构造出利用方式。 分析 首先对该木马进行格式化,以增强代码的可读性。得到如下代码 <jsp:root xmlns:jsp"http://java.sun.com/JSP/Page" vers…

基于Python开发的五子棋小游戏(源码+可执行程序exe文件+程序配置说明书+程序使用说明书)

一、项目简介 本项目是一套基于Python开发的五子棋小游戏&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Python学习者。 包含&#xff1a;项目源码、项目文档、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&a…

斯坦福小镇升级版——AI-Town搭建指南

导语&#xff1a; 8月份斯坦福AI小镇开源之后&#xff0c;引起了 AIGC 领域的强烈反响&#xff0c;但8月份还有另一个同样非常有意义的 AI-Agent 的项目开源&#xff0c;a16z主导的 AI-Town 本篇文章主要讲解如何搭建该项目&#xff0c;如有英文基础或者对这套技术栈熟悉&#…

TCP之三次握手四次挥手

在前面的文章中我们了解到http是基于TCP/IP协议的&#xff0c;这篇文章我们来了解一下TCP/IP。 一、TCP与UDP 1、UDP 基于非连接。类似于写信&#xff0c;不能保证对方能不能接收到&#xff0c;接收到的内容是否完整&#xff0c;顺序是否正确。 优缺点&#xff1a;性能损耗小…

云数据库知识学习——概述

一、云计算是云数据库兴起的基础 云计算是分布式计算、并行计算、效用计算、网络存储、虚拟化、负载均衡等计算机和网络技术发展融合的产物。云计算是由一系列可以动态升级和被虚拟化的资源组成的&#xff0c;用户无需掌握云计算的技术&#xff0c;只要通过网络就可以访问这些资…

Maven中导入jQuery,前端页面中引用jQuery

第一步pom文件中&#xff0c;配置maven坐标。 第二步&#xff0c;在前端页面中引用jQuery 注&#xff1a;该前端页面需要在web根目录即webapp目录下。可认为在maven中导入jQuery后&#xff0c;jquery.min.js文件放在目录webapp/webjars/jquery/3.3.1下。

HarmonyOS开发:探索动态共享包的依赖与使用

前言 所谓共享包&#xff0c;和Android中的Library本质是一样的&#xff0c;目的是为了实现代码和资源的共享&#xff0c;在HarmonyOS中&#xff0c;给开发者提供了两种共享包&#xff0c;HAR&#xff08;Harmony Archive&#xff09;静态共享包&#xff0c;和HSP&#xff08;H…

Spring整合tomcat的WebSocket详细逻辑(图解)

主要解决存在的疑问 为什么存在2种spring整合websocket的方式&#xff0c;一种是使用ServerEndpoint注解的方式&#xff0c;一种是使用EnableWebSocket注解的方式&#xff0c;这2种有什么区别和联系&#xff1f;可以共存吗&#xff1f;它们实现的原理是什么&#xff1f;它们的各…