分类目录: html5
前端实现OSS的断点续传
Post date:
Author: cyy
标签: OSS
Number of comments: no comments
前端实现OSS的断点续传
实现效果:
准备工作:
需要有一个后端给你提供STS签名
直接开始(普通HTML版本):
参考自:https://blog.csdn.net/weixin_34354173/article/details/86016192
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>cyytest</title>
<script src="http://gosspublic.alicdn.com/aliyun-oss-sdk-5.2.0.min.js"></script>
<script src="http://libs.baidu.com/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<div id="app">
<div id="up_wrap"></div>
<div class="form-group">
<input type="file" id="file" multiple="multiple"/>
</div>
<div class="form-group">
<input type="button" class="btn btn-primary" id="file-button" value="Upload"/>
<input type="button" class="btn btn-primary" id="Continue-button" value="Continue"/>
</div>
</div>
</body>
<script type="text/javascript">
var appServer = 'http://127.0.0.1:8088/api/file/STS';
var bucket = 'testtttt';
var region = 'oss-cn-shanghai';
var uid = 'x';//用户标识
var urllib = OSS.urllib;
var Buffer = OSS.Buffer;
var OSS = OSS.Wrapper;
//获取授权STSToken,并初始化client
var applyTokenDo = function (func) {
var url = appServer;
return urllib.request(url, {
method: 'GET'
}).then(function (result) {
var creds = JSON.parse(result.data);
console.log('sts--->>', creds.data)
var client = new OSS({
region: region,
accessKeyId: creds.data.accessKeyId,
accessKeySecret: creds.data.accessKeySecret,
stsToken: creds.data.securityToken,
bucket: bucket
});
return func(client);
});
};
//上传文件
var uploadFile = function (client) {
if (upfiles.length < 1)
return;
upfile = upfiles[0];
var file = upfile.file;
var key = upfile.name;
var objkey = key + "_" + uid + ".json";
return client.multipartUpload(key, file, {
progress: function (p, cpt, res) {
console.log("p:", p);
console.log("cpt:", cpt);
if (cpt != undefined) {
var content = JSON.stringify(cpt);
client.put(objkey, 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('upload success: ', res);
upfiles.shift();
client.delete(objkey);
applyTokenDo(uploadFile);
});
};
//断点续传文件
var reUploadFile = function (client) {
if (upfiles.length < 1)
return;
upfile = upfiles[0];
var file = upfile.file;
var key = upfile.name;
var objkey = key + "_" + uid + ".json";
return client.get(objkey).then(function (res) {
var data = JSON.parse(res.content);
data.file = file;
console.log('断点续传-->>', data)
return client.multipartUpload(key, file, {
checkpoint: data,
progress: function (p, cpt, res) {
console.log("p:", p);
console.log("cpt:", cpt);
if (cpt != undefined) {
var content = JSON.stringify(cpt);
console.log('objkey?--》》', objkey)
client.put(objkey, 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 (ret) {
console.log('upload success:', ret);
upfiles.shift();
client.delete(objkey);
applyTokenDo(uploadFile);
});
});
};
//文件上传队列
var upfiles = [];
$(function () {
//初始化文件上传队列
$("#file").change(function (e) {
var ufiles = $(this).prop('files');
var htm = "";
for (var i = 0; i < ufiles.length; i++) {
htm += "<dl><dt>" + ufiles[i].name + "</dt><dd><div class=\"progress\"><div id=\"progress-bar_" + i + "\" class=\"progress-bar\" role=\"progressbar\" aria-valuenow=\"0\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"min-width: 2em;\">0%</div></div></dd></dl>";
upfiles.push({
num: i,
name: ufiles[i].name,
file: ufiles[i]
})
}
console.log('upfiles:', upfiles);
$("#up_wrap").html(htm);
})
//上传
$("#file-button").click(function () {
applyTokenDo(uploadFile);
})
//续传
$("#Continue-button").click(function () {
applyTokenDo(reUploadFile);
})
})
</script>
</html>
爆改成vue版本:
引入依赖
npm install ali-oss --save
<template>
<div class="w100 content justcenter flexcolum hand">
<div class="upload-box relative content alicenter justcenter" >
<i class="el-icon-plus" style="font-size:36px"></i>
<input type="file" class="hand" :multiple="multiple" id="file" @change="chooseDone($event)" />
</div>
<div v-for="(item, index) in upfiles" :key="index">
<p>{{item.name}}</p>
<el-progress :percentage="Math.floor(item.p*100)" v-show="item.p<1"></el-progress>
<el-progress :percentage="Math.floor(item.p*100)" status="success" v-show="item.p>=1"></el-progress>
</div>
</div>
</template>
<script>
const OSS = require('ali-oss')
export default {
name: 'index',
data () {
return {
bucket: 'test',
region: 'oss-cn-shanghai',
uid: 'x',
urllib: null,
Buffer: OSS.Buffer,
OSS: null,
upfiles: []
}
},
props: {
// 是否多选
multiple: {
type: Boolean,
default: () => {
return true
}
}
},
methods: {
// 文件选择完毕
chooseDone(evet, from) {
var ufiles
if (from !== 'drag') ufiles = evet.target.files
else ufiles = evet
for (var i = 0; i < ufiles.length; i++) {
const suffixArr = ufiles[i].name.split('.')
this.upfiles.push({
originalName: ufiles[i].name,
fileSize: ufiles[i].size,
suffix: suffixArr[suffixArr.length - 1],
p: 0,
num: i,
name: ufiles[i].name,
file: ufiles[i]
})
}
this.ctn() // 开始上传
},
// 请求阿里获取token
applyTokenDo (func) {
this.$get('http://127.0.0.1:8088/api/file/STS').then((result) => {
this.OSS = new OSS({
region: this.region,
accessKeyId: result.data.accessKeyId,
accessKeySecret: result.data.accessKeySecret,
stsToken: result.data.securityToken,
bucket: this.bucket
})
func(this.OSS)
}).catch(() => {})
},
// 从0 上传
uploadFile (client) {
let letFiles = this.upfiles.filter(f => f.p !== 1)
if (letFiles.length < 1) {
this.uploadFileGoGoGo(this.upfiles)
return false
}
var upfile = letFiles[0]
var file = upfile.file
var key = 'kgs/' + upfile.name
var objkey = key + '_' + this.uid + '.json'
let that = this
return client.multipartUpload(key, file, {
progress: (p, cpt, res) => {
this.upfiles.forEach(f => {
if (f.name === upfile.name) {
f.p = p
}
})
if (cpt !== undefined) {
var content = JSON.stringify(cpt)
client.put(objkey, new that.Buffer(content))
}
return function (done) {
done()
}
}
}).then((res) => {
client.delete(objkey)
this.applyTokenDo(this.uploadFile)
})
},
// 断点续传文件
reUploadFile(client) {
let letFiles = this.upfiles.filter(f => f.p !== 1)
if (letFiles.length < 1) {
this.uploadFileGoGoGo(this.upfiles)
return false
}
var upfile = letFiles[0]
var file = upfile.file
var key = 'kgs/' + upfile.name
var objkey = key + '_' + this.uid + '.json'
return client.get(objkey).then((res) => {
var data = JSON.parse(res.content)
data.file = file
return client.multipartUpload(key, file, {
checkpoint: data,
progress: (p, cpt, res) => {
this.upfiles.forEach(f => {
if (f.name === upfile.name) {
f.p = p
}
})
if (cpt !== undefined) {
var content = JSON.stringify(cpt)
client.put(objkey, new this.Buffer(content))
}
return (done) => {
done()
}
}
}).then((ret) => {
client.delete(objkey)
this.applyTokenDo(this.uploadFile)
}).catch(() => {
console.log('multipartUpload error')
})
}).catch(() => {
this.go()
})
},
// 文件全部传输到oss完毕
uploadFileGoGoGo(files) {
this.$emit('uploadFiles', this.upfiles)
},
// 从0上传文件
go() {
this.applyTokenDo(this.uploadFile)
},
// 断点续传文件
ctn() {
if (this.upfiles.length < 1) {
return false
}
this.applyTokenDo(this.reUploadFile)
}
},
mounted () {
}
}
</script>
<style scoped>
.upload-box{
padding: 20px;
box-sizing: border-box;
border-radius: 5px;
border: 1px dashed #dcdcdc;
}
#file{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
z-index: 2;
}
</style>