大文件上传阿里云oss,分片、断点续传进度条展示

这篇具有很好参考价值的文章主要介绍了大文件上传阿里云oss,分片、断点续传进度条展示。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前端页面展示
大文件上传阿里云oss,分片、断点续传进度条展示

1.背景

大文件如果不采用分片上传会导致卡死、内存占用过高导致程序奔溃等一些列问题。 通常在文件大于100 MB的情况下,建议采用分片上传的方法,通过断点续传和重试,提高上传成功率。如果在文件小于100 MB的情况下使用分片上传,且partSize设置不合理的情况下,可能会出现无法完整显示上传进度的情况。对于小于100 MB的文件,建议使用简单上传的方式。

2.使用STS临时访问凭证访问OSS

因为采用前端js上传,为避免暴露阿里云账号访问密钥(AccessKey ID和AccessKey Secret),强烈建议您使用临时访问凭证的方式执行OSS相关操作
请访问阿里云官网 : 阿里云官网STS操作
临时访问凭证包括临时访问密钥(AccessKey ID和AccessKey Secret)和安全令牌(SecurityToken)。

3.从后台获取临时token获取操作:

   public class OssGetStsToken {

    private static final Logger log = LoggerFactory.getLogger(OssGetStsToken.class);

    private static String accessKeyId = "您的accessKeyId";
    private static String accessKeySecret = "您的accessKeySecret";
    private static String roleArn = "您的roleArn";
    private static String roleSessionName = "您的roleSessionName ";

    /**
     * token失效时间,单位秒(不设置默认1小时,这里设置20分钟)
     */
    private static final Long durationSeconds = 1200L;
    private static final String ENDPOINT = "sts.aliyuncs.com";


    /**
     * 获取STStoken接口
     *
     * @param:
     * @return: StsTokenVO
     */
    public static StsTokenVO getStsToken(String bucketName) {
        StsTokenVO tokenVO = new StsTokenVO();
        try {
            // 添加endpoint(直接使用STS endpoint,前两个参数留空,无需添加region ID)
            DefaultProfile.addEndpoint("", "", "Sts", ENDPOINT);
            // 构造default profile(参数留空,无需添加region ID)
            IClientProfile profile = DefaultProfile.getProfile("", accessKeyId, accessKeySecret);
            // 用profile构造client
            DefaultAcsClient client = new DefaultAcsClient(profile);
            final AssumeRoleRequest request = new AssumeRoleRequest();
            request.setMethod(MethodType.POST);
            request.setRoleArn(roleArn);
            request.setRoleSessionName(roleSessionName);
//             request.setDurationSeconds(durationSeconds);
            // 针对该临时权限可以根据该属性赋予规则,格式为json,没有特殊要求,默认为空
            // request.setPolicy(policy); // Optional
            final AssumeRoleResponse response = client.getAcsResponse(request);
            AssumeRoleResponse.Credentials credentials = response.getCredentials();
            tokenVO.setKeyId(credentials.getAccessKeyId());
            tokenVO.setKeySecret(credentials.getAccessKeySecret());
            tokenVO.setSecurityToken(credentials.getSecurityToken());
            tokenVO.setBucketName(bucketName);
            return tokenVO;
        } catch (ClientException e) {
            log.error("获取阿里云STS临时授权权限失败,错误信息:" + e);
            throw new BaseException("获取阿里云STS临时授权权限失败,错误信息:" + e);
        }
    }
}

StsTokenVO文章来源地址https://www.toymoban.com/news/detail-515663.html

 @Data
public class StsTokenVO implements Serializable {

    /**
     * 访问密钥标识
     */
    private String keyId;
    /**
     * 访问密钥
     */
    private String keySecret;
    /**
     * 安全令牌
     */
    private String securityToken;

    /**
     * oss-bucket
     */
    private String bucketName;
}

4.js直传代码

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>OSS上传大文件</title>
</head>
<head>
    <th:block th:include="include :: header('新增ota文件')"/>
    <th:block th:include="include :: jasny-bootstrap-css"/>
</head>

<form>
    <div class="form-group">
        <label class="col-sm-3 control-label">选择ota包:</label>
        <div class="fileinput fileinput-new col-sm-6" data-provides="fileinput">
                    <span id="changeFile" class="btn btn-white btn-file">
                        <span  class="fileinput-new">选择ota包</span>
                        <span  class="fileinput-exists">更改</span>
                        <input type="file" id="firmware" required multiple="multiple"/>
                    </span>
            <span class="fileinput-filename"></span>
            <a href="#" id="labels" class="close fileinput-exists" onclick="empty()" data-dismiss="fileinput" style="float: none">&times</a>
        </div>
        
        <!-- 进度条展示   -->
        <div id="up_wrap" style="margin-left: 420px;width: 800px;"></div>
        
    </div>
</form>
    <div class="row" style="line-height:95px">
        <div class="col-sm-offset-5 col-sm-10">
            <button type="button" class="btn btn-sm btn-warning" id="pause" onclick="pause()"><i class="fa fa-close"> </i> 暂停</button>&nbsp;
            <button type="button" class="btn btn-sm btn-success" id="resume" onclick="resume()"><i class="fa fa-cloud-upload"> </i> 恢复上传</button>&nbsp;
            <button type="button" class="btn btn-sm btn-primary" id="btnsubmit" onclick="submitHandler()"><i class="fa fa-check"> </i> 保 存</button>&nbsp;
            <button type="button" class="btn btn-sm btn-danger"  id="closesubmit" onclick="closeItem()"><i class="fa fa-reply-all"> </i> 关 闭 </button>
        </div>
    </div>
<body>
<th:block th:include="include :: jasny-bootstrap-js"/>
<script th:src="@{/js/plugins/spark-md5.js}"></script>
<script th:src="@{/js/aliyun-oss-sdk-6.16.0.min.js}"></script>
<script th:inline="javascript">
    // 表单提交的路径
    const prefix = ctx + "web/ota"
    // 获取STSToken路径
    const stsRequest = ctx + "web/stsToken";
    // 表单校验
    $("#form-ota-add").validate({
        focusCleanup: true
    });


    //初始化文件上传队列
    var upfiles = [];
    $(function () {
        $("#firmware").change(function (e) {
            var ufiles = $(this).prop('files');
            for (var i = 0; i < ufiles.length; i++) {
                upfiles.push({
                    num: i,
                    name: ufiles[i].name,
                    file: ufiles[i]
                })
            }
            console.log('upfiles:', upfiles);
        })
    })

    // 初始化加载client对象
    var bucket = '';  // bucket名称
    var region = 'oss-cn-shenzhen'; // 地区
    var Buffer = OSS.Buffer;
    var OSS = OSS;
    var md5 = '';
    // 定义中断点数据保存。
    let client;
    let abortCheckpoint;
    var suffix ='';
    var applyTokenDo = function (func) {
        $.ajax({
            url: stsRequest + "/credential",
            type: "get",
            data: '',
            contentType: false,
            processData: false,
            success: function (result) {
                console.log(result);
                client = new OSS({
                    region: region,
                    accessKeyId: result.keyId, //访问密钥标识
                    accessKeySecret: result.keySecret, // 访问密钥
                    stsToken: result.securityToken, // 安全令牌
                    bucket: result.bucketName,
                });
                bucket=result.bucketName;
                return func(client);
            }
        });
    };

    function empty() {
        upfiles = [];
        $("#firmware").val("");
        let a=document.getElementById("firmware");
        a.length=0
    }

    var path ='ota/beta/';
    // 上传文件 并且计算进度,以进度条方式展示
    var uploadFile = function (client) {
        console.log(client);
        if (upfiles.length < 1) {
            return;
        }

        var timestamp = (new Date()).valueOf();
        var file = upfiles[0].file;
        var key = upfiles[0].name;
        $('#btnsubmit').attr('disabled', true);
        $('#closesubmit').attr('disabled', true);
        $("#pause").show();
        $("#resume").show();
        suffix = path + timestamp + key.substring(key.length - 4);
        // 分片上传
        return client.multipartUpload(suffix, file, {
            progress: function (p, cpt, res) {
                abortCheckpoint = cpt;
                let ps = parseInt((p.toFixed(2)) * 100);
                console.log("上传进度:", ps + '%');
                console.log("cpt:", cpt);
                let html = '';
                html = '<dl><dt></dt><dd><div class="progress"><div  class="progress-bar"  role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width:' + ps + '%"><span>' + ps + '%</span></div></div></dd></dl>';
                $("#up_wrap").html(html);
                if (p == 1) {
                    const url = `https://${bucket}.${region}.aliyuncs.com/${suffix}`; // 最终上传完成后的下载url
                    console.log("url:", url);
                    // oss key(删除文件需要用到)
                    $("#ossKey").val(suffix);
                    // 完整的下载地址
                    $("#downloadUrl").val(url);
                    // 文件大小
                    $("#fileSize").val(file.size);
                    // 表单提交
                    if ($.validate.form()) {
                        $.operate.save(prefix + "/add", $('#form-ota-add').serialize());
                    }
                }
                if (cpt != undefined) {
                    var content = JSON.stringify(cpt);
                    client.put(suffix, new Buffer(content));
                }
                return function (done) {
                    var bar = document.getElementById('progress-bar_' + upfile.num);
                    bar.style.width = Math.floor(p * 100) + '%';
                    bar.innerHTML = Math.floor(p * 100) + '%';
                    done();
                }
            }
        }).then(function (res) {
            console.log('上传成功: ', res);
            upfiles.shift();
            client.delete(key);
            applyTokenDo(uploadFile);
        });
    };

    // 表单提交
    function submitHandler() {
        var form = $("#form-ota-add").get(0);
        var formdata = new FormData(form);
        console.log(formdata);
        if ($.validate.form()) {
            $("#closesubmit").attr("disabled",true);
            $("#btnsubmit").attr("disabled",true);
            $("#changeFile").css("pointer-events", "none");
            $("#labels").css("visibility","hidden");
            $.ajax({
                url: prefix + "/addCheck",
                type: "post",
                data: formdata,
                contentType: false,
                processData: false,
                success: function (result) {
                    if (result){
                        applyTokenDo(uploadFile);
                    }else {
                        $.modal.alertError("已有存在的版本号和型号文件!");
                        $("#closesubmit").attr("disabled",false);
                        $("#btnsubmit").attr("disabled",false);
                        empty();
                    }
                }
            });
        }
    }

    // 监听续传按钮,单击”恢复上传“后继续上传。
    // 暂停
    function pause() {
        console.log(client);
        client.cancel();
    }

    // 恢复上传
    function resume() {
        resumeUpload();
    }
    //  隐藏按钮
    $(function(){
        $("#pause").hide();
        $("#resume").hide();
    });

    // 异步断点续传方法 (恢复上传)
    const resumeUpload = async () => {
        console.log(client);
        if (upfiles.length < 1) {
            return;
        }
        var file = upfiles[0].file;
        var key = upfiles[0].name;
        return client.multipartUpload(suffix, file, {
            checkpoint: abortCheckpoint,
            progress: function (p, cpt, res) {
                abortCheckpoint = cpt;
                let ps = parseInt((p.toFixed(2)) * 100);
                console.log("上传进度:", ps + '%');
                console.log("cpt:", cpt);
                let html = '';
                html = '<dl><dt></dt><dd><div class="progress"><div  class="progress-bar"  role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width:' + ps + '%"><span>' + ps + '%</span></div></div></dd></dl>';
                $("#up_wrap").html(html);
                if (p == 1) {
                    const url = `https://${bucket}.${region}.aliyuncs.com/${suffix}`; // 最终上传完成后的下载url
                    console.log("url:", url);
                    $("#ossKey").val(suffix);
                    $("#downloadUrl").val(url);
                    $("#fileSize").val(file.size);
                    // 表单提交
                    if ($.validate.form()) {
                        $.operate.save(prefix + "/add", $('#form-ota-add').serialize());
                    }
                }
                if (cpt != undefined) {
                    var content = JSON.stringify(cpt);
                    client.put(suffix, new Buffer(content));
                }
                return function (done) {
                    var bar = document.getElementById('progress-bar_' + upfile.num);
                    bar.style.width = Math.floor(p * 100) + '%';
                    bar.innerHTML = Math.floor(p * 100) + '%';
                    done();
                }
            }
        }).then(function (res) {
            console.log('上传成功: ', res);
            upfiles.shift();
            client.delete(key);
            applyTokenDo(uploadFile);
        });
    };


    /**
     * 根据选择的文件生成 MD5值
     */
    document.getElementById('firmware').addEventListener('change', function () {
        var sta = new Date().getTime();
        var blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice,
            file = this.files[0],
            chunkSize = 52428800,                             // 分片大小 (50MB)
            chunks = Math.ceil(file.size / chunkSize),
            currentChunk = 0,
            spark = new SparkMD5.ArrayBuffer(),
            fileReader = new FileReader();

        fileReader.onload = function (e) {
            console.log('read chunk nr', currentChunk + 1, 'of', chunks);
            spark.append(e.target.result);                   // Append array buffer
            currentChunk++;

            if (currentChunk < chunks) {
                loadNext();
            } else {
                var end = new Date().getTime() - sta;
                console.info('耗时:', end)
                $("#otaMd5").val(spark.end());
                console.info('MD5:', $("#otaMd5").val())
            }
        };
        fileReader.onerror = function () {
            console.warn('oops, something went wrong.');
        };
        function loadNext() {
            var start = currentChunk * chunkSize,
                end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;
            fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
        }
        loadNext();
    });
</script>
</body>
</html>

到了这里,关于大文件上传阿里云oss,分片、断点续传进度条展示的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • minio&前后端分离上传视频/上传大文件——前后端分离断点续传&minio分片上传实现

    minio&前后端分离上传视频/上传大文件——前后端分离断点续传&minio分片上传实现

    🍀🍀🍀🍀分布式文件系统-minio: 第一章:分布式文件系统介绍与minio介绍与使用(附minio java client 使用) 第二章:minio前后端分离上传视频/上传大文件——前后端分离断点续传minio分片上传实现 断点续传指的是在下载或上传时,将下载或上传任务(一个文件或一个压缩包

    2024年02月03日
    浏览(27)
  • 【SpringBoot整合系列】SpringBoot 实现大文件分片上传、断点续传及秒传

    【SpringBoot整合系列】SpringBoot 实现大文件分片上传、断点续传及秒传

    小文件(图片、文档、视频)上传可以直接使用很多ui框架封装的上传组件,或者自己写一个input 上传,利用FormData 对象提交文件数据,后端使用spring提供的MultipartFile进行文件的接收,然后写入即可。 但是对于比较大的文件,比如上传2G左右的文件(http上传),就需要将文件

    2024年04月16日
    浏览(11)
  • springboot整合vue2-uploader文件分片上传、秒传、断点续传

    springboot整合vue2-uploader文件分片上传、秒传、断点续传

    vue-simple-uploader 是基于 simple-uploader.js 封装的vue上传插件。它的优点包括且不限于以下几种: 支持文件、多文件、文件夹上传;支持拖拽文件、文件夹上传 可暂停、继续上传 错误处理 支持“秒传”,通过文件判断服务端是否已存在从而实现“秒传” 分片上传 支持进度、预估

    2024年02月06日
    浏览(13)
  • 基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传

    基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传

    1. 前言 文件上传 小文件(图片、文档、视频)上传可以直接使用很多ui框架封装的上传组件,或者自己写一个input 上传,利用FormData 对象提交文件数据,后端使用spring提供的MultipartFile进行文件的接收,然后写入即可。但是对于比较大的文件,比如上传2G左右的文件(http上传

    2024年02月06日
    浏览(7)
  • 【万字长文】Vue+SpringBoot实现大文件秒传、断点续传和分片上传完整教程(提供Gitee源码)

    前言:最近在实际项目中碰到一个需求,客户可能会上传比较大的文件,如果采用传统的文件上传方案可能会存在服务器压力大、资源浪费甚至内存溢出的一些安全风险,所以为了解决一系列问题,需要采用新的技术方案来实现大文件的上传;空闲的时候参考了网上的一些相

    2024年02月12日
    浏览(8)
  • springboot 、html分片上传,断点续传

    后端代码 注意:合并分片代码中: Files.write(mergedFilePath, Files.readAllBytes(chunkFilePath), StandardOpenOption.APPEND); 如果不设置该值 StandardOpenOption.APPEND ,无法打开合并后的文件 前端代码

    2024年02月05日
    浏览(5)
  • Vue 大文件切片上传实现指南包会,含【并发上传切片,断点续传,服务器合并切片,计算文件MD5,上传进度显示,秒传】等功能

    Vue 大文件切片上传实现指南包会,含【并发上传切片,断点续传,服务器合并切片,计算文件MD5,上传进度显示,秒传】等功能

            在Web开发中,文件上传是一个常见的功能需求,尤其是当涉及到大文件上传时,为了提高上传的稳定性和效率,文件切片上传技术便显得尤为重要。通过将大文件切分成多个小块(切片)进行上传,不仅可以有效减少单次上传的数据量,降低网络波动对上传过程的

    2024年04月28日
    浏览(7)
  • 前端大文件分片上传 进度条展示 上传暂停、开始、取消

    前端大文件分片上传 进度条展示 上传暂停、开始、取消

    实现的效果: 1、多个大文件(支持10个G以上)分片上传 2、进度条展示进度 3、控制文件上传暂停和取消 实现关键点: 1、文件预处理(md5计算、请求和进度处理等) 2、分片上传的流程(查询已上传分片、文件合并等) 3、文件的暂停、开始、取消 首先使用file类型的input框

    2024年04月26日
    浏览(10)
  • 前端 + 后端 实现分片上传(断点续传/极速秒传)

    先记录下,后面有时间再去实现 (已实现,可参考 SpringBoot+vue文件上传下载预览大文件分片上传文件上传进度 SpringBoot+vue 大文件分片下载) 可参考链接:vue上传大文件/视频前后端(java)代码 前端slice分片上传,后端用表记录分片索引和分片大小和分片总数,当接受完最后

    2023年04月17日
    浏览(8)
  • SpringBoot整合minio实现断点续传、分片上传(附源码)

    SpringBoot整合minio实现断点续传、分片上传(附源码)

    在Web开发中,大文件的上传是必不可少的功能之一。本文将介绍如何使用SpringBoot整合minio实现一个简单的大文件上传网站。 项目下载 gitee:https://gitee.com/wusupweilgy/springboot-vue.git 前端:vue2、element-ui组件、axios 后端:springboot、minio、mybatis-plus、redis 断点续传 分片上传 前端显示

    2024年02月04日
    浏览(8)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包