大文件上传demo,前端基于Uppy,后端基于koa

这篇具有很好参考价值的文章主要介绍了大文件上传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 ,运行项目后如下图:

大文件上传demo,前端基于Uppy,后端基于koa,Koa,学习,前端,大文件上传

后端

项目创建具体见:Koa学习1:初始化项目

运行项目后如下图:
大文件上传demo,前端基于Uppy,后端基于koa,Koa,学习,前端,大文件上传

整合

现在处理一下,让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.data
      console.log("数据是:", res.data)
    })
}

</script>

<style scoped>
.upload-container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 700px;
}
</style>

效果图
大文件上传demo,前端基于Uppy,后端基于koa,Koa,学习,前端,大文件上传

简单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`);
});

大文件上传demo,前端基于Uppy,后端基于koa,Koa,学习,前端,大文件上传
大文件上传demo,前端基于Uppy,后端基于koa,Koa,学习,前端,大文件上传

大文件上传、断点续传

实现分片上传并且支持断点续传需要基于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}`);
});

执行效果

大文件上传demo,前端基于Uppy,后端基于koa,Koa,学习,前端,大文件上传
上传完成后会生成两个文件,如下:
第一个就是上传的文件,会变成一个二进制文件
第二个是这个文件的一下信息
大文件上传demo,前端基于Uppy,后端基于koa,Koa,学习,前端,大文件上传
前端Uppy库也会返回文件信息,如下图:

大文件上传demo,前端基于Uppy,后端基于koa,Koa,学习,前端,大文件上传

代码

代码放到码云上了,感兴趣的可以自己看一下

前端

地址
https://gitee.com/idonotyou/vue-upload

运行文章来源地址https://www.toymoban.com/news/detail-700880.html

npm i 
npm run dev

后端

地址
https://gitee.com/idonotyou/koa-upload

运行

npm i 
npm run dev

到了这里,关于大文件上传demo,前端基于Uppy,后端基于koa的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Node后端框架Express与Koa接口统一响应封装

    以前在写 SpringBoot 全栈开发的系列文章中全栈开发之后端脚手架:SpringBoot集成MybatisPlus代码生成,分页,雪花算法,统一响应,异常拦截,Swagger3接口文档,有提到对后端接口的响应数据进行统一的封装,方便前端或者第三方进行数据获取与对接工作;统一响应一般包含状态

    2024年02月05日
    浏览(30)
  • Koa学习笔记

    生成 package.json 文件,记录项目的依赖 生成 .git 隐藏文件夹,.git 的本地仓库 创建 .gitignore 文件,添加不提交文件的名称 记录项目笔记 安装 Koa 框架 在项目根目录创建 src 文件夹,并文件夹中创建 main.js 文件,文件内容如下: 启动方法 使用 nodemon 工具 安装 修改项目启动脚

    2024年02月01日
    浏览(28)
  • node.js 学习 -- koa

    1. 安装 Koa 框架 2. 引入 3. 配置中间件 4. 监听端口 1. 配置文件 安装  dotenv  包 创建  .env  文件 在当前目录下创建  config  文件夹,用来保存配置文件,并添加 config.default.js 改写 主进程内容 路由:根据不同的 URL,调用对应处理函数 1. 安装 koa-router koa-router 官方文档 步骤:

    2024年02月06日
    浏览(35)
  • 基于Promise.resolve实现Koa请求队列中间件

    本文作者为360奇舞团前端工程师 最近在做一个 AIGC 项目,后端基于 Koa2 实现。其中有一个需求就是调用兄弟业务线服务端 AIGC 能力生成图片。但由于目前兄弟业务线的 AIGC 项目也是处于测试阶段,能够提供的服务器资源有限,当并发请求资源无法满足时,会响应【服务器繁忙

    2024年02月13日
    浏览(26)
  • 图片上传流程&前端上传文件&后端保存文件&并返回图片地址

    也是在最近一点时间写小demo 遇到的一些问题 比如在用户界面,用户选择本地的一张照片,前端把照片传到后端,后端怎么把照片保存到服务器,然后返回给 图片线上地址。也是找了一些文章,然后分享下。  技术 前端:react 后端:egg.js(node框架) base64 转换  转二进制 保存

    2024年02月02日
    浏览(64)
  • 第三章 Electron 使用Koa以及Koa-Router

    据网上的资料显示,Koa 是下一代的 Node.js 的 Web 框架。是express原班人马打造,同样用于构建服务端web application的。旨在提供一个更小型、更富有表现力、更可靠的 Web 应用和 API 的开发基础。扯这些没用的,它就是提供给我们构建API服务的。 快捷式路由(app.get、app.put、app.po

    2024年02月07日
    浏览(25)
  • nodejs框架 express koa介绍以及从零搭建 koa 模板

    操作 请求类型 url 返回 获取所有 GET /users 获取单个 GET /users/1 新增 POST /users 修改部分 PATCH /users/1 修改全部 PUT /users/1 删除 DELETE /users/1 一个路由由 请求方法 路径 和 回调函数组成 匹配 404 路由 获取请求报文参数 获取动态路由参数 获取 post 请求体参数 下载 响应 中间件本质是

    2024年02月14日
    浏览(26)
  • 前端上传文件夹或文件至后端(SpringBoot)

    前端上传文件夹使用的是 input 标签的file属性,最重要的是 webkitdirectory 这个属性,有了这个属性之后input才可以选择文件夹,但也只能选择文件夹了。 在webkitdirectory的官方文档里有对该属性的说明。 我们可以在这基础上做延伸,做一个表单来上传文件夹: form要加上 enctype=“

    2024年02月05日
    浏览(46)
  • 【Koa】[NoSQL] Koa中相关介绍和使用Redis & MongoDB增删改查

    目标: 了解什么是关系型数据库 关系型数据库,是指采用了 关系模型 来组织数据的数据库。 关系模型,指的就是 二维表格模型 ,而一个关系型数据库就是由 二维表及其之间的联系 所组成的一个数据组织。 关系型数据库一般都支持数据库事务,必须具备 ACID 特性。 ACID 分

    2024年02月16日
    浏览(29)
  • 【无人机三维路径规划】基于开普勒优化算法KOA求解复杂山地环境下无人机三维路径规划研究附matlab代码

     ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进, 代码获取、论文复现及科研仿真合作可私信。 🍎个人主页:Matlab科研工作室 🍊个人信条:格物致知。 更多Matlab完整代码及仿真定制内容点击👇 智能优化算法       神经网络预测       雷达通信    

    2024年02月03日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包