基于OSS前端直传的分片上传以及断点续传

news2024/9/27 7:15:47

一、大文件分片上传

原型

大文件如果直接上传的话由于nginx的限制会导致响应500报错,或者响应时间过长导致响应超时

image.png

并且大文件上传有如下缺点

  1. 上传时间长: 对于大文件,直接上传可能需要较长时间,特别是在网络速度较慢或不稳定的情况下。这可能会导致用户等待时间过长,影响用户体验。
  2. 内存占用: 直接上传大文件可能会占用大量内存,特别是在客户端进行文件读取和上传的情况下。这可能会导致客户端程序消耗大量内存资源,甚至在上传大型文件时出现内存溢出的情况。
  3. 网络传输中断: 在网络不稳定的环境下,上传大文件可能会遇到网络传输中断的问题。这会导致上传过程中断,需要重新开始上传,从而增加了额外的时间和网络流量。
  4. 服务器端资源消耗: 直接上传大文件可能会对服务器端资源造成较大负担,特别是在高并发情况下。大文件上传会占用服务器的网络带宽和处理能力,可能会影响服务器的稳定性和性能。

解决方案

根据这种情况我们往往采用分片上传来进行解决
分片上传:将一个大文件在前端进行分片,并将每个小分片进行编码异步上传至后端服务器中。后端收到这些分片后解码并按顺序进行重组

优点:

  1. 提高上传速度。在网络带宽允许的情况下,可以同时上传多个文件片段,从而加快了整个文件的上传速度
  2. 方便前端做上传进度条处理,提高用户体验
  3. 断点续传,分片上传过程中若出现了网络问题或其他问题导致上传中断,只需要上传中断的部分而不需要上传整个文件,提高了上传的可靠性

由于公司采用的是阿里云的oss对象存储,oss中已经我们提供了分片上传这样一项服务,因此我们只需要在前端简单的配置便可以实现分片上传并返回进度条,前端甚至不需要手动分片

import OSS from "ali-oss";
interface OSSConfig {
  accessKeyId: string;
  accessKeySecret: string;
  region: string;
  bucket: string;
}

export class OssService {
  private client: any;
  constructor(ossConfig: OSSConfig) {
    this.client = new OSS({
      accessKeyId: ossConfig.accessKeyId,
      accessKeySecret: ossConfig.accessKeySecret,
      region: ossConfig.region,
      bucket: ossConfig.bucket,
    });
  }

  // 开始分片上传。
  async multipartUpload(
    ossPath: string,
    file: File,
    progressCallback: (progress: number) => void
  ) {
    return new Promise(async (resolve, reject) => {
      try {
        const result = await this.client.multipartUpload(ossPath, file, {
          // 回调返回进度条
          progress: async (p: number) => {
            progressCallback(p);
          },
        });
        resolve(result);
      } catch (e: any) {
        if (e.code === "ConnectionTimeoutError") {
          reject("TimeoutError");
        }
        reject(e);
      }
    });
  }
}
import { OssService } from "@/util/OSS/index";


// OSS 配置
const ossConfig = {
  accessKeyId: "accessKeyId",
  accessKeySecret: "accessKeySecret",
  endpoint: "endpoint",
  bucket: "bucket",
  region: "region",
};

const oss = new OssService(ossConfig);


// 以naiveui UI框架 的自定义上传 举例
async function customRequest({
  file,
  data,
  onFinish,
  onError,
}: UploadCustomRequestOptions) {
  try {
    // 工具类引用
    const res = await oss.multipartUpload(
      `/file/${file.file?.name}`,
      file.file as File,
      (e) => {
        // 返回进度条,做进度条处理
        console.log(e);
      }
    );
    onFinish();
    message.success("上传成功");
  } catch (e) {
    onError();
    message.error("上传失败");
  }
}

大致效果

动画.gif
动画2.gif

缺点

目前的OSS配置项是保存在前端,因此安全性不高。即使通过后端加密后返回最终也需要在前端进行解密,对于懂点逆向的人来说,需要破解难度不高
因此,需要将OSS的配置项存储到后端,前端通过接口请求后端返回OSS的一个临时授权凭证(STS),根据这个临时授权凭证便可以进行前端直传到OSS服务器

实现方法

  1. 通过官网进行配置

使用STS临时访问凭证访问OSS_对象存储(OSS)-阿里云帮助中心

  1. 编写生成sts临时凭证接口
import * as OSS from 'ali-oss';
import * as STS from '@alicloud/sts-sdk';
import ossConfig, { STSConfig } from 'src/config/oss';
/**
   * 获取签名
   */
  async getSignature() {
    const stsEndpoint = STSConfig.stsEndpoint;
    const accessKeyId = STSConfig.accessKeyId;
    const accessKeySecret = STSConfig.accessKeySecret;
    const roleArn = STSConfig.roleArn;

    // 生成签名,策略等信息
    const sts = new STS({
      endpoint: stsEndpoint,
      accessKeyId: accessKeyId,
      accessKeySecret: accessKeySecret,
    });
    // 响应给客户端的签名和策略等信息
    return {
      ...(await sts.assumeRole(roleArn, 'RamOssTest')),
    };
  }
  1. 前端拿到临时凭证后再进行直传
import OSS from "ali-oss";
import { oss_Config } from "@/config";
import { getSignature } from "@/api/common/upload";

export class OssService {
  private client: any;
  // 定义中断点。
  protected abortCheckpoint: any;

  constructor() {
    this.initOss();
  }
  // 新增凭证请求
  async initOss() {
    const { Credentials } = (await getSignature()).data;
    this.client = new OSS({
      accessKeyId: Credentials.AccessKeyId,
      accessKeySecret: Credentials.AccessKeySecret,
      stsToken: Credentials.SecurityToken,
      region: oss_Config.region,
      bucket: oss_Config.bucket,
    });
  }

  // 开始分片上传。
  async multipartUpload(
    ossPath: string,
    file: File,
    progressCallback: (progress: number) => void
  ) {
    return new Promise(async (resolve, reject) => {
      try {
        const result = await this.client.multipartUpload(ossPath, file, {
          checkpoint: this.abortCheckpoint,
          progress: async (p: number, cpt: any) => {
            // 为中断点赋值。
            this.abortCheckpoint = cpt;
            progressCallback(p);
          },
        });
        resolve(result);
      } catch (e: any) {
        // 捕获超时异常。
        if (e.code === "ConnectionTimeoutError") {
          reject("TimeoutError");
        }
        reject(e);
      }
    });
  }

  // 暂停上传。
  pause() {
    this.client.cancel();
  }
}

// 自定义文件上传 & 续传
async function customRequest({
  file,
  onFinish,
  onError,
}: UploadCustomRequestOptions) {
  try {
    // 文件重命名
    const fileExtension = getFileExtension(file.file?.name as string);
    // const newFileName = (await calculateFileHash(file.file as File)) + fileExtension;
    const newFileName = uuid() + fileExtension;

    // 设置上传进度
    processing.value = true;

    const res: any = await oss.multipartUpload(
      `/file/${newFileName}`,
      file.file as File,
      (e) => {
        percentage.value = Math.floor(e * 100);
      }
    );

    processing.value = false;
    file.url = `http://${oss_Config.bucket}.${oss_Config.endpoint}${res.name}`;
    fileList.value.push(file);

    onFinish();
    emit("update:value", fileList.value);
    message.success("上传成功");
  } catch (e) {
    onError();
    processing.value = false;
    message.error("上传失败");
  }
}

原理

image.png


二、断点续传

断点续传是一种网络传输技术,用于在文件传输过程中实现中断后的续传操作。其核心思想是在文件传输过程中保存传输的断点信息,以便在传输中断或失败后能够在之后的某个时间点恢复传输,而不需要重新开始传输整个文件

结合阿里云OSS我们也很容易可以实现断点续传

只需要在OSS工具类中新加两个地方即可实现!

  async multipartUpload(
    ossPath: string,
    file: File,
    progressCallback: (progress: number) => void
  ) {
    return new Promise(async (resolve, reject) => {
      try {
        const result = await this.client.multipartUpload(ossPath, file, {
          checkpoint: this.abortCheckpoint, // 新加
          progress: async (p: number, cpt: any) => {
            // 为中断点赋值。
            this.abortCheckpoint = cpt; // 新加
            progressCallback(p);
          },
        });
        resolve(result);
      } catch (e: any) {
        // 捕获超时异常。
        if (e.code === "ConnectionTimeoutError") {
          reject("TimeoutError");
        }
        reject(e);
      }
    });
  }

效果

动画3.gif

原理

image.png

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

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

相关文章

深入搞懂Checkpoint调优基础及原理

前言 在执行大量写操作的系统上,调优检查点对于获得良好的性能至关重要。然而,检查点是我们经常发现混淆和配置问题的地方之一,无论是在社区邮件列表中,还是在为客户提供支持和咨询期间。这篇文章旨在解释检查点是什么——目的和数据库如何实现它——以及如何调优它们。 注…

Leetcode—74. 搜索二维矩阵【中等】

2024每日刷题&#xff08;149&#xff09; Leetcode—74. 搜索二维矩阵 实现代码 class Solution { public:bool searchMatrix(vector<vector<int>>& matrix, int target) {int m matrix.size();int n matrix[0].size();int l 0;int r m * n;int mid -1…

如何解决 Nginx 与无服务器架构的集成问题?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01; 文章目录 如何解决 Nginx 与无服务器架构的集成问题&#xff1f; 如何解决 Nginx 与无服务器架构的集成问题&#xff1f; 在当今的云计算时代&#xff0c;无服务器架构因…

AI有关的学习和python

一、基本概念 AIGC&#xff08;AI Generated content AI 生成内容&#xff09; AI生成的文本、代码、图片、音频、视频。都可以成为AIGC。 Generative AI&#xff08;生成式AI&#xff09;所生成的内容就是AIGC AI指代计算机人工智能&#xff0c;模仿人类的智能从而解决问题…

JAVA中的泛型机制详解

1.泛型的概念 java泛型是java5引入的一个特性&#xff0c;它允许我们为类&#xff0c;接口&#xff0c;方法指定类型参数&#xff0c;从而提供编译时类型安全检查。泛型的本质是参数化类型&#xff0c;即在声明类&#xff0c;接口或者方法时不指定具体的类型&#xff0c;而是使…

sed利用脚本处理文件

一、sed是什么 sed 命令是利用脚本来处理文本文件。它可以依照脚本的指令来处理、编辑文本文件。主要用来自动编 辑一个或多个文件、简化对文件的反复操作、编写转换程序等。 二、sed的原理 读入新的一行内容到缓存空间&#xff1b; 从指定的操作指令中取出第一条指令&…

C++ 列式内存布局数据存储格式 Arrow

Apache Arrow 优点 : 高性能数据处理&#xff1a; Arrow 使用列式内存布局&#xff0c;这特别适合于数据分析和查询操作&#xff0c;因为它允许对数据进行高效批量处理&#xff0c;减少CPU缓存未命中&#xff0c;从而提升处理速度。 零拷贝数据共享&#xff1a; Arrow …

【PyTorch】基于YOLO的多目标检测项目(一)

【PyTorch】基于YOLO的多目标检测项目&#xff08;一&#xff09; 【PyTorch】基于YOLO的多目标检测项目&#xff08;二&#xff09; 目标检测是对图像中的现有目标进行定位和分类的过程。识别的对象在图像中显示有边界框。一般的目标检测方法有两种&#xff1a;基于区域提议的…

javaEE-02-servlet

文章目录 Servlet 技术servlet程序示例通过实现Servlet接口实现Servlet程序通过继承 HttpServlet 实现 Servlet 程序 Servlet的声明周期 ServletConfig 类ServletContext 类HttpServletRequest 类请求的转发 HttpServletResponse 类请求重定向 HTTP 协议GET 请求Post请求常用请…

三维影像系统PACS源码,图像存储与传输系统,应用于医院中管理医疗设备如CT,MR等产生的医学图像的信息系统

PACS&#xff0c;即图像存储与传输系统&#xff0c;是应用于医院中管理医疗设备如CT&#xff0c;MR等产生的医学图像的信息系统。目标是支持在医院内部所有关于图像的活动&#xff0c;集成了医疗设备&#xff0c;图像存储和分发&#xff0c;数字图像在重要诊断和会诊时的显示&a…

unity ui toolkit的使用

UIToolkitExamples (github)样例 GitHub - ikewada/UIToolkitExamples: チュートリアル動画「使ってみようUI Toolkit」のためのサンプルプロジェクトです官网 Unity - Manual: UI Toolkit视频教程 使用 UI Toolkit - 上集_哔哩哔哩_bilibili 使用 UI Toolkit - 下集_哔哩哔哩_…

vue3前端开发-小兔鲜项目-使用pinia插件完成token的本地存储

vue3前端开发-小兔鲜项目-使用pinia插件完成token的本地存储&#xff01;实际业务开发中&#xff0c;token是一个表示着用户登录状态的重要信息&#xff0c;它有自己的生命周期。因此&#xff0c;这个参数值必须实例化存储在本地中。不能跟着pinia。因为pinia是基于内存设计的模…

go语言day18 reflect反射

Golang-100-Days/Day16-20(Go语言基础进阶)/day19_Go语言反射.md at master rubyhan1314/Golang-100-Days (github.com) 一、interface接口 接口类型内部存储了一对pair(value,Type) type interface { type *Type // 类型信息 data unsafe.Pointer // 指向具体数据 } 1)创建R…

Git基本原理讲解、常见命令、Git版本回退、Git抛弃本地分支拉取仓库最新分支

借此机会写篇博客汇总一下自己去公司实习之后遇到的一些常见关于Git的操作。 Git基本认识 Git把数据看作是对小型文件系统的一组快照&#xff0c;每次提交更新&#xff0c;或在Git中保存项目状态时&#xff0c;Git主要对当时的全部文件制作一个快照并保存这个快照的索引。同时…

嵌入式C++、MQTT、数据库、Grafana、机器学习( Scikit-learn):智能建筑大数据管理平台(代码示例)

项目概述 智能建筑管理系统&#xff08;Intelligent Building Management System, IBMS&#xff09;是一个集成多种技术的复杂系统&#xff0c;旨在通过智能化手段提升建筑的管理效率、节能效果和居住舒适度。该系统涉及嵌入式系统、物联网&#xff08;IoT&#xff09;、大数据…

数据库-触发器,存储过程

按照题目要求完成下列题目&#xff1a; 1.触发器 mysql> use mydb16_trigger; Database changed mysql> create table goods(-> gid char(8) primary key,-> name varchar(10),-> price decimal(8,2),-> num int); Query OK, 0 rows affected (0.01 sec)my…

01 Redis引入和概述

Redis引入和概述 一、Redis的历史和发展过程 ​ Redis是在2008年由意大利的一家创业公司Merzia的创始人Salvatore Sanfilippo(萨尔瓦托.圣菲利波)创造的。 ​ 当时&#xff0c;Salvatore 正在开发一款基于MySQL的网站实时统计系统LLOOGG&#xff0c;然而他发现MySQL的性能并…

VAE、GAN与Transformer核心公式解析

VAE、GAN与Transformer核心公式解析 VAE、GAN与Transformer&#xff1a;三大深度学习模型的异同解析 【表格】VAE、GAN与Transformer的对比分析 序号对比维度VAE&#xff08;变分自编码器&#xff09;GAN&#xff08;生成对抗网络&#xff09;Transformer&#xff08;变换器&…

计算机网络(四)数字签名和CA认证

什么是数字签名和CA认证&#xff1f; 数字签名 数字签名的过程通常涉及以下几个步骤&#xff1a; 信息哈希&#xff1a;首先&#xff0c;发送方使用一个哈希函数&#xff08;如SHA-256&#xff09;对要发送的信息&#xff08;如电子邮件、文件等&#xff09;生成一个固定长度…

GIS场景升级:支持多种影像协议与天气效果

在GIS场景编辑领域&#xff0c;升级视效的需求日益增加。有一款名为山海鲸可视化的免费工具&#xff0c;本人亲测能够完美满足这一需求。山海鲸可视化不仅支持多种GIS影像协议&#xff08;如TMS、WMS、WMTS等&#xff09;&#xff0c;还能一键添加天气效果&#xff0c;瞬间提升…