将AWS S3大文件文件上传相关的API集成为js文件,功能包括 多文件并行上传、文件分片上传、断点续传、文件分片合成、上传暂停、取消上传、文件上传进度条显示

news2024/11/25 4:03:58

地址

https://github.com/gk-1213/easy-s3/tree/main

easy-s3

将AWS S3大文件文件上传相关的API集成为js文件,功能包括多文件并行上传、文件分片上传、断点续传、文件分片合成、上传暂停、取消上传、文件上传进度条显示。

暂时不包括文件分片下载相关功能,可后续迭代。

使用方法:下载s3.js文件并引入到需要使用的js文件中,即可使用
具体使用示例可参照下文中的第二点

一、API

1、init

传入以下参数,初始化s3客户端

在这里插入图片描述

2、fileChange

加入文件上传任务,使用该方法

传入参数:

fileChange({ fileList, bucket, changeStatus, getSuspend, changeSharding } )   //注意,传入的是一个map

/**
	fileList:文件信息数组,其内部元素的结构为
	{
		percentage: 0,//该文件的上传进度,如果不需要展示进度的话,可以不传 false
		status: 'wait',//文件上传的状态  true
		file: file,//需要上传的文件   true
		needSuspend: false,//是否暂停  true
		sharding: [],//分片数组,该文件已经上传了那些分片  true
		shardSize: 32 * 1024 * 1024//该文件每个分片的大小   true
	}
*/

/**
	bucket:文件上传到s3上的bucket名称
*/

/**
	changeStatus:一个事件,前端页面定义的可以改变文件上传的状态的事件
	示例:
	changeStatus(name, val) {//传入参数 name:文件名称   val:文件状态
            for (let i = 0; i < this.fileList.length; i++) {
                if (this.fileList[i].file.name == name) {
                    this.fileList[i].status = val;
                    if (val === 'success') {
                        this.fileList[i].percentage = 100;
                    }
                    break;
                }
            }
        },

*/


/**
	getSuspend:一个事件,前端页面定义的可以获取该文件上传是否暂停的事件
	示例:
	getSuspend(name) {//传入参数 name : 该文件的名称
            let suspend = this.fileList.filter(e => {
                return e.file.name === name;
            });
            if (suspend.length != 0) {
                return suspend[0].needSuspend;
            }
            return false;
     },
*/
/**
	changeSharding:前端页面定义的可以改变该文件的已经上传分片的事件
	示例:
	changeSharding(name, shard) {//传入参数 name:文件的名称  shard:文件已经上传的分片
            for (let i = 0; i < this.fileList.length; i++) {
                if (this.fileList[i].file.name === name) {
                    this.fileList[i].sharding = shard;
                    //改变进度条
                    let size = 0;
                    for (let j = 0; j < shard.length; j++) {
                        size += shard[j].Size;
                    }
                    //计算该文件的上传进度
                    this.fileList[i].percentage = ((size / this.fileList[i].file.size) * 100).toFixed(1) - 0;
                    return;
                }
            }
        },
*/

3、cancel

取消一个文件的上传

cancel({ bucket, file })//注意,传入的是一个map
/**
	bucket:文件上传到s3上的bucket名称
*/
/**
	file:取消的文件
*/

4、getWorker

判断某个文件是否正在上传,或已经在上传任务中了

使用场景:对文件上传任务点击继续时,判断是否需要将该文件加入到上传任务队列中,因为对该文件的上传 短时间内频繁点击暂停、继续按钮时,可能会导致重复加入同一个文件的上传任务

(只有该任务终止,才应该加入上传队列)

(文件上传分片之前会判断该文件是否已经暂停上传,暂停的话,就会终止任务;或者文件分片上传出错的话,也会终止任务)

getWorker(file)
/**
	file:文件
*/
返回值:false:没有正在上传   true:正在上传

二、封装的API使用示例

<template>
    <div class="about">
        <div style="display: flex;justify-content: center;align-items: center;">
            <el-form label-position="left" label-width="120px" :model="s3Clent" style="width:500px">
                <el-form-item label="endpoint">
                    <el-input v-model="s3Clent.endpoint"></el-input>
                </el-form-item>
                <el-form-item label="region">
                    <el-input v-model="s3Clent.region"></el-input>
                </el-form-item>
                <el-form-item label="signatureVersion">
                    <el-input v-model="s3Clent.signatureVersion"></el-input>
                </el-form-item>
                <el-form-item label="accessKeyId">
                    <el-input v-model="s3Clent.credentials.accessKeyId"></el-input>
                </el-form-item>
                <el-form-item label="secretAccessKey">
                    <el-input v-model="s3Clent.credentials.secretAccessKey"></el-input>
                </el-form-item>
            </el-form>
        </div>
        <input multiple v-show="false" ref="fileRef" type="file" @change="inputFile">
        <el-button type="primary" @click="upload()">点击上传文件</el-button>

        <div v-for="f in fileList" :key="f.file.name">
            <div style="margin-top:50px;display: flex;align-items: center;justify-content: center;" v-if="f.show">
                <div style="margin-right:20px;font-size:15px;font-weight:60">
                    {{ f.file.name }}
                </div>
                <el-progress :percentage="f.percentage" style="width:500px"></el-progress>
                <div style="margin-left:20px">
                    <span v-if="f.status == 'err'" style="color:#F56C6C">上传错误</span>
                    <span v-else-if="f.status == 'same name'" style="color:#F56C6C">同名文件</span>
                    <span v-else-if="f.status == 'success'" style="color:#67C23A">上传成功</span>
                    <span v-else-if="f.status == 'suspend'" style="color:#409EFF">已暂停</span>
                </div>
                <div style="margin-left:20px">
                    <!-- 暂停按钮 -->
                    <el-button type="primary" icon="el-icon-video-pause" circle v-if="f.status === 'wait'"
                        @click="suspendButton(f)"></el-button>
                    <!-- 继续按钮 -->
                    <el-button type="primary" icon="el-icon-video-play" circle v-if="f.status === 'suspend'"
                        @click="continuedButton(f)"></el-button>
                    <!-- 取消按钮 -->
                    <el-button type="danger" icon="el-icon-close" circle v-if="f.status === 'suspend' || f.status === 'err'"
                        @click="cancelButton(f)"></el-button>
                    <!-- 重试按钮 -->
                    <el-button type="primary" icon="el-icon-refresh-right" circle v-if="f.status === 'err'"
                        @click="continuedButton(f)"></el-button>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
import { init, cancel, fileChange, getWorker } from '../assets/js/s3.js'
export default {
    data() {
        return {
            fileList: [],//存储上传文件列表
            s3Clent: {
                endpoint: "http://minio.3wok.top",
                region: 'us-east-1',
                s3ForcePathStyle: true,
                signatureVersion: 'v4',
                forcePathStyle: true,

                credentials: {
                    accessKeyId: 'xxxxxxxxxxx',
                    secretAccessKey: 'xxxxxxx'
                },
            }//s3配置文件
        }
    },
    methods: {
        async continuedButton(file) {
            file.needSuspend = false;
            file.status = 'wait';
            const isInQueue = getWorker(file.file);
            console.log("isInQueue", isInQueue)
            if (isInQueue === false) {
                //如果任务队列中没有这个文件上传任务,那么就加入到任务队列中
                fileChange({ fileList: [file], bucket: 'test', changeStatus: this.changeStatus, getSuspend: this.getSuspend, changeSharding: this.changeSharding });
            }

        },
        async cancelButton(f) {
            await cancel({ bucket: 'test', file: f.file });
            this.fileList = this.fileList.filter(e => {
                return e.file.name !== f.file.name;
            });
        },
        upload() {
            this.$refs.fileRef.dispatchEvent(new MouseEvent('click'));
        },
        inputFile(event) {
            let files = event.target.files;
            let addFile = [];
            for (let i = 0; i < files.length; i++) {
                this.fileList.push({
                    percentage: 0,
                    status: 'wait',
                    show: true,
                    file: files[i],
                    needSuspend: false,
                    sharding: [],//分片数组
                    shardSize: 32 * 1024 * 1024//每个分片的大小
                });
                addFile.push({
                    percentage: 0,
                    status: 'wait',
                    show: true,
                    file: files[i],
                    needSuspend: false,
                    sharding: [],//分片数组
                    shardSize: 32 * 1024 * 1024//每个分片的大小
                });
            }
            fileChange({ fileList: addFile, bucket: 'test', changeStatus: this.changeStatus, getSuspend: this.getSuspend, changeSharding: this.changeSharding })
        },
        //暂停
        suspendButton(file) {
            file.needSuspend = true;
            file.status = 'suspend';
        },
        //修改状态
        changeStatus(name, val) {
            //TODO 改变进度条
            for (let i = 0; i < this.fileList.length; i++) {
                if (this.fileList[i].file.name == name) {
                    this.fileList[i].status = val;
                    if (val === 'success') {
                        this.fileList[i].percentage = 100;
                    }
                    break;
                }
            }
        },
        //修改分片数组
        changeSharding(name, shard) {
            console.log(shard)
            for (let i = 0; i < this.fileList.length; i++) {
                if (this.fileList[i].file.name === name) {
                    this.fileList[i].sharding = shard;
                    //改变进度条
                    let size = 0;
                    for (let j = 0; j < shard.length; j++) {
                        size += shard[j].Size;
                    }
                    this.fileList[i].percentage = ((size / this.fileList[i].file.size) * 100).toFixed(1) - 0;
                    return;
                }
            }
        },
        //获取该文件是否需要暂停
        getSuspend(name) {
            let suspend = this.fileList.filter(e => {
                return e.file.name === name;
            });
            if (suspend.length != 0) {
                return suspend[0].needSuspend;
            }
            return false;
        },

    },
    created() {
        //创建客户端
        init(this.s3Clent);
    }
}
</script>

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

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

相关文章

网工实操基础学习23.07.05

1.交换机&#xff0c;路由器 交换机的作用是链接同一个网络下的所有设备&#xff0c;如果有无线设备加入&#xff0c;需要添加AP&#xff08;无线接入点&#xff09;设备在交换机层次上 路由器的作用是将不同网络下的设备链接 2.IP地址 划分网段&#xff1a;网络位、网段、…

C++第三方开发库matplotlib-cpp

Matplotlib-cpp是一个用于在C中绘制图表的开源库。它提供了与Python的Matplotlib库类似的功能&#xff0c;使得在C环境下进行数据可视化变得更加便捷。基于Matplotlib-cpp&#xff0c;我们可以使用各种绘图函数和样式选项来创建各种类型的图表&#xff0c;包括折线图、散点图、…

单片机第一季:零基础11——实时时钟DS1302

目录 1&#xff0c;DS1302 时钟芯片介绍 2&#xff0c;BCD码介绍 3&#xff0c;涉及到的寄存器 3.1&#xff0c;控制寄存器 3.2&#xff0c;日历/时钟寄存器 3.3&#xff0c;DS1302 的读写时序 4&#xff0c;相关代码 这一章我们来学习DS1302 时钟芯片&#xff0c…

数据结构栈和队列

3.栈和队列 3.1栈和队列的定义和特点 栈和队列是两种常用的、重要的数据结构栈和队列是限定插入和删除只能在表的 “ 端点 ”进行的线性表栈和队列是线性表的子集&#xff08;是插入和删除位置受限的线性表&#xff09; 栈的应用&#xff1a; ​ 由于栈的操作具有后进先出的…

国内疫情地图和省级疫情地图

基础地图演示 from pyecharts.charts import Mapfrom pyecharts.options import VisualMapOpts map Map() data [ ("北京", 99), ("上海", 199), ("湖南", 299), ("台湾", 199), ("安徽", 299), ("广州", 399…

干货满满-运营校园跑腿小程序

校园跑腿是指在校园内提供代办、送餐、购物等服务的一种形式。学生可以通过跑腿服务解决一些日常生活中的繁琐事务&#xff0c;节省时间和精力。在校园跑腿小程序运营中&#xff0c;你可以尝试以下方法进行运营管理&#xff1a; &#xff08;1&#xff09;注册或加入相关的校园…

fdbus和proto编译

1. 下载protobuf和FDBUS 1.下载 FDBUS需要用到protobuf&#xff0c;所以需要提前安装好protobuf。 protobuf下载地址 https://gitee.com/it-monkey/protocolbuffers/ fdbus下载地址 https://gitee.com/jeremyczhen/fdbus 2. Windows编译 生成vs工程 打开CMake&#xff…

(vue)vue项目中引入外部字体

(vue)vue项目中引入外部字体 效果&#xff1a; 第一步 放置字体包&#xff0c;在assets下创建一个fonts文件夹&#xff0c;放入下载的字体文件 第二步 创建一个font.css文件用于定义这个字体包的名字 第三步 在App.vue的css中将这个css文件引入 第四步 页面使用 font-famil…

NumPy 专业人士应该掌握的 45 个技能

一、说明 NumPy&#xff08;或Numeric Python&#xff09;是每个数据科学和机器学习项目的核心。 整个数据驱动的生态系统在某种程度上依赖于NumPy及其核心功能。这使它成为 Python 有史以来最重要和改变游戏规则的库之一。 鉴于NumPy由于其无与伦比的潜力而在工业界和学术界具…

java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法

文章目录 一、记录文件相关操作方法二、代码1.读取路径返回List\<File>2.读取路径返回List\<String>3.删除文件夹4.删除文件 一、记录文件相关操作方法 二、代码 1.读取路径返回List<File> import org.slf4j.LoggerFactory; import org.slf4j.Logger;impo…

【学会动态规划】按摩师(11)

目录 动态规划怎么学&#xff1f; 1. 题目解析 2. 算法原理 1. 状态表示 2. 状态转移方程 3. 初始化 4. 填表顺序 5. 返回值 3. 代码编写 写在最后&#xff1a; 动态规划怎么学&#xff1f; 学习一个算法没有捷径&#xff0c;更何况是学习动态规划&#xff0c; 跟我…

es通过rest接口_search、_delete_by_query查询与删除数据

1、rest接口查询数据 rest查询: http://localhost:9200/index_name/_search 查询表达式&#xff1a; {"query": {"wildcard": {"accountID": {"value": "v*"}}} }postman请求截图&#xff1a; 2、使用Rest接口删除数据 …

基于Lucene实现校园搜索引擎——太强搜索

完整资料进入【数字空间】查看——搜索"writebug" 实验环境 win10 一、实验内容 综合运用搜索引擎体系结构和核心算法方面的知识&#xff0c;基于开源资源搭建搜索引擎&#xff0c;具体包括如下几点&#xff1a; 抓取清华校园网内绝大部分资源&#xff0c;并且进行…

【NLP】温和解读:transformer的核心思想

变压器模型及其关键组件的概述。 一、介绍 在这篇博文中&#xff0c;我将讨论本世纪最具革命性的论文“注意力是你所需要的一切”&#xff08;Vaswani et al.&#xff09;。首先&#xff0c;我将介绍自我注意机制&#xff0c;然后介绍变形金刚的架构细节。在之前的博客文章《从…

【数据分析 最火 全集干货】Anaconda的安装及使用

关于我的专栏&#xff1a; 接下来会有许多关于“数据分析”的文章哦&#xff0c;记得看哦&#xff01;&#xff01;&#xff01; Python最详细最全面基础合集_adaptation_T_C的博客-CSDN博客 有兴趣&#xff0c;需要 的小伙伴可以免费订阅哦&#xff01;&#xff01;&#x…

阿里 P8 架构师 20 年经验!总结成微服务设计企业架构转型之道

前言 本文涉及两个方面的知识体系&#xff0c;即企业架构知识体系和软件架构知识体系。 企业架构和软件架构虽然都与 IT 相关&#xff0c;但其知识体系是完全不同的两个领域。一般而言&#xff0c;搞企业架构的人士不明白软件架构的细节和实现&#xff0c;而从事软件架构的架…

如何恢复损坏/删除的 Word 文件

有关如何修复不可读的 Microsoft Word 文件或 Rich Text 文件中的文本的分步说明。这些说明有助于从损坏的*.doc、*.docx、*.dot、*.dotx、*.rtf文件&#xff08;任何版本和大小&#xff09;中提取文本&#xff0c;只需单击几下&#xff1a; 从此处下载奇客数据恢复 &#xff…

React AntDesign写一个导出数据的提示语 上面有跳转的路径,或者点击知道了,关闭该弹层

效果如下&#xff1a; 代码如下&#xff1a; ForwardDataCenterModal(_blank);export const ForwardDataCenterModal (target?: string) > {let contentBefore React.createElement(span, null, 数据正在处理中&#xff0c;请稍后前往);let contentAfter React.creat…

【如何训练一个中译英翻译器】LSTM机器翻译模型训练与保存(二)

系列文章 【如何训练一个中译英翻译器】LSTM机器翻译seq2seq字符编码&#xff08;一&#xff09; 目录 系列文章1、加载训练集2、训练集数据处理3、网络搭建4、启动训练5、模型保存6、模型加载与推理 基于LSTM训练一个翻译器&#xff0c;要怎么做呢&#xff1f;其实很简单&am…

大厂案例 - 实时分析引擎

文章目录 概述内容收获思路建议 概述 网络安全态势越来越复杂&#xff0c;传统的基于单点的防护和攻击检测系统在应对现代网络攻击方面有着很大的局限性。 基于大数据平台&#xff0c;通过流式实时分析技术可以对全局网络空间进行实时的分析和异常检测&#xff0c;解决单点很…