前端 vue 直传 华为云OBS(BrowserJS 断点续传方法)

需求:

可多个文件同时上传,需要显示文件名、上传进度、上传速度,可以暂停、继续
前端 vue 直传 华为云OBS(BrowserJS 断点续传方法)_第1张图片

开始

1、搭建OBS服务环境相关请参考官网教程 点击跳转

2、下载OBS BrowserJS SDK开发包 点击跳转,引入esdk-obs-browserjs-without-polyfill-3.19.5.min.js文件

import ObsClient from "../util/esdk-obs-browserjs-without-polyfill-3.19.5.min.js";

3、创建OBS实例

<script>
import ObsClient from "../util/esdk-obs-browserjs-without-polyfill-3.19.5.min.js";

var obsClient; // obs实例

export default {
    ...
    mounted() {
        // 创建ObsClient实例
        obsClient = new ObsClient({
            access_key_id: '*** Provide your Access Key ***',       
            secret_access_key: '*** Provide your Secret Key ***',       
            server : 'https://your-endpoint'
        });
    }
</script>

4、断点续传上传

直接采用官方示例,复制过来后,修改好桶名、分片等信息后,直接可以上传成功,但暂停等功能并不好用,我们需要对其进行修改

首先上代码,代码中有详细注释,底部还有部分代码的说明

/**
 * 上传函数
 * @param {file} file 文件
 * @param {Object} fileObj 本条上传文件相关的信息
 */
setObs(file,fileObj) {
    let _this = this
    fileObj.cp = {}
    fileObj.hook = ""
    obsClient.uploadFile(
    {
        Bucket: xxx,
        Key: xxx,
        SourceFile: file,
        PartSize: xxx,
        TaskNum: 3,
        // 获取上传进度的回调函数
        ProgressCallback: function (transferredAmount,totalAmount) {
        _this.progressCallback.call(_this,fileObj, transferredAmount, totalAmount)
        },
        // 获取上传事件的回调函数
        EventCallback: function (eventType, eventParam, eventResult) {
        // 处理事件响应
        },
        // 获取断点续传控制参数的回调函数
        ResumeCallback: function (resumeHook, uploadCheckpoint) {
        // 获取取消断点续传上传任务控制参数
        fileObj.hook = resumeHook;
        // 存储断点续传记录对象
        fileObj.cp = uploadCheckpoint;
        },
    },
    // 成功、失败回调函数
    function (err, result) {
        if (err) {
        _this.errType.call(_this,file,fileObj) // 报错后执行(包括用户手动暂停)
        } else {
        if (result.CommonMsg.Status < 300 && result.InterfaceResult) {
            _this.successSetFile() // 成功后执行
        } else {
            _this.statusSet(fileObj, 'error')  // 将文件上传状态改为失败
        }
        }
    }
    );
},

/**
 * 上传中回调函数
 * @param {Object} fileObj 本条上传文件相关的信息
 * @param {Number} transferredAmount 已上传的字节数
 * @param {Number} totalAmount 总字节数
 */
progressCallback(fileObj, transferredAmount, totalAmount) {
    if (fileObj.amount && transferredAmount) {
        let speed = ((transferredAmount - fileObj.amount) / 1048576) >= 1 ? ((transferredAmount - fileObj.amount) / 1048576).toFixed(2) + 'MB' : ((transferredAmount - fileObj.amount) / 1024).toFixed(2) + 'KB'
        fileObj.speed = speed // 上传速度
    }
    fileObj.amount = transferredAmount // 已上传的字节数(用于计算上传速度)
    this.statusSet(fileObj, Math.floor((transferredAmount * 100.0) / totalAmount)); //  // 将文件上传状态改为进度条
},

/**
 * err报错(手动暂停、取消)后执行
 * @param {file} file 文件
 * @param {Object} fileObj 本条上传文件相关的信息
 */
errType(file, fileObj) {
    let _this = this
    if (fileObj.cancelManually) { // 用于判断是手动暂停的
        fileObj.errSetFileArguments = [file,fileObj]
    } else { // 如果不是手动暂停的则自动重新执行
        fileObj.errNumber ? fileObj.errNumber += 1 : fileObj.errNumber = 1
        if (fileObj.errNumber > 50) return this.statusSet(fileObj, 'error') // 重新执行次数过多后将状态改为失败
        _this.errSetFile(file,fileObj) // 自动重新执行
    }
},

/**
 * 报错(手动暂停、取消)后重新执行
 * @param {Object} file 文件(fileList中errSetFileArguments)
 * @param {Object} fileObj fileList中对应参数(fileList中errSetFileArguments)
 */
errSetFile(file,fileObj) {
    let _this = this
    // 删除手动运行判断
    fileObj.errSetFile = false
    obsClient.uploadFile(
        {
            UploadCheckpoint: fileObj.cp,
            // 获取上传进度的回调函数
            ProgressCallback: function (transferredAmount,totalAmount) {
                _this.progressCallback.call(_this,fileObj, transferredAmount, totalAmount)
            },
            EventCallback: function (eventType, eventParam, eventResult) {
            // 处理事件响应
            },
            ResumeCallback: function (resumeHook, uploadCheckpoint) {
            // 获取取消断点续传上传任务控制参数
            fileObj.hook = resumeHook;
            // 存储断点续传记录对象
            fileObj.cp = uploadCheckpoint;
            },
        },
        function (err, result) {
            if (err) {
                _this.errType.call(_this,file,fileObj)
            } else {
                if (result.CommonMsg.Status < 300) {
                    let key = result.InterfaceResult.Key
                    _this.successSetFile() // 成功后执行
                } else {
                    _thisthis.statusSet(fileObj, 'error') //  // 将文件上传状态改为失败
                }
            }
        }
    );
},
/**
 * 成功后执行
 */
successSetFile() {...}
/**
 * 暂停上传
 * @param {Object} item fileList-item
 */
pauseUpload(item, type) {
    item.cancelManually = true // 用于判断是手动暂停的
    item.hook.cancel()
    this.statusSet(item, 'pause') // 将文件上传状态改为暂停
},
/**
 * 继续上传
 * @param {Object} item fileList-item
 */
continueUpload(fileObj) {
    this.errSetFile(...fileObj.errSetFileArguments)
}

代码说明

进度条、上传速度:

ProgressCallback参数回调函数中,有三个形参,分别为已上传的字节数、总字节数、已使用的时间(秒),通过该函数可以算出进度条和上传速度

// fileObj.amount 为上一次保存的已上传的字节数
/**
 * 上传函数
 * @param {Number} transferredAmount 已上传的字节数
 * @param {Number} totalAmount 总字节数
 */
ProgressCallback: function (transferredAmount,totalAmount) {
    if (fileObj.amount && transferredAmount) {
        let speed = ((transferredAmount - fileObj.amount) / 1048576) >= 1 ? ((transferredAmount - fileObj.amount) / 1048576).toFixed(2) + 'MB' : ((transferredAmount - fileObj.amount) / 1024).toFixed(2) + 'KB'
        fileObj.speed = speed // 上传速度
    }
    fileObj.amount = transferredAmount // 已上传的字节数(用于计算上传速度)
    Math.floor((transferredAmount * 100.0) / totalAmount); // 进度条
}

开始、暂停

ResumeCallback参数回调函数中,可以获取断点续传控制参数的回调函数和断点续传记录对象,我们需要将两个参数存起来。断点续传控制参数用于调用暂停和继续;断点续传记录对象用于在暂停后继续执行

obsClient.uploadFile的第二个参数是处理上传结束后是否的回调函数,在用户暂停的时候也会走这个回调函数

我在做暂停功能时的思路是:在执行上传后,通过ResumeCallback得到断点续传控制参数和断点续传记录对象(#1)。在用户点击暂停时候,通过调用断点续传控制参数.cancel()暂停上传,同时存储一个字段用于判断是手动暂停的(#2);然后在回调函数中通过这个字段判断如果是手动暂停的,保存相关信息(#3),在用户点击继续时再次调用断点续传接口,继续上传任务(#4)。

#1

// fileObj 本条上传文件相关的信息
// 获取断点续传控制参数的回调函数
ResumeCallback: function (resumeHook, uploadCheckpoint) {
    // 获取取消断点续传上传任务控制参数
    fileObj.hook = resumeHook;
    // 存储断点续传记录对象
    fileObj.cp = uploadCheckpoint;
},

#2

/**
 * 暂停上传
 * @param {Object} item fileList-item
 */
pauseUpload(item, type) {
    item.cancelManually = true // 用于判断是手动暂停的
    item.hook.cancel()
    this.statusSet(item, 'pause') // 将文件上传状态改为暂停
},

#3

// 成功、失败回调函数
obsClient.uploadFile(
    {...},
    function (err, result) {
        if (err) {
            if (fileObj.cancelManually) { // true: 手动暂停的
                fileObj.errSetFileArguments = [file,fileObj] // 用户点击继续时执行所需要的参数[文件,本条上传文件相关的信息]
            } else {
                ...
            }
        }
    }

#4

/**
 * 继续上传
 */
this.errSetFile(...fileObj.errSetFileArguments)

—END—

你可能感兴趣的:(vue,JS,vue,js,obs,webbrowser)