前端实现OSS的断点续传

前端实现OSS的断点续传

实现效果:

前端实现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>
前端实现OSS的断点续传
原文链接:,转发请注明来源!

发表评论