vue+element+oss實現前端分片上傳和斷點續傳

純前端實現: 切片上傳 斷點續傳斷點續傳需要在切上上傳的基礎上實現

前端之前上傳OSS,無需後端提供接口。先上完整代碼,直接復制,將new OSS裡的參數修改成自己公司OSS相關信息後可用,如遇問題,請繼續往下看。

oss官方文檔

https://help.aliyun.com/document_detail/111268.html?spm=a2c4g.11186623.6.1111.5a583a07LknRUO

代碼允許所需環境:vue + element + ali-oss

安裝ali-oss: cnpm install ali-oss

代碼實現

<template>
 <div class="dashboard-editor-container">
 <el-upload
  class="upload-demo"
  action=""
  ref="upload"
  :file-list="fileList"
  :limit="2"
  :on-change="handleChange"
  :on-remove="handleRemove"
  :auto-upload="false"
  accept=""
 >
  <el-button slot="trigger" size="small" type="primary">選取文件</el-button>
  <el-button style="margin-left: 10px;" size="small" type="success" @click="submitForm">上傳到服務器</el-button>
  <el-button style="margin-left: 10px;" size="small" type="success" @click="resumeUpload">繼續</el-button>
  <el-button style="margin-left: 10px;" size="small" type="success" @click="stopUplosd">暫停</el-button>
  <el-button style="margin-left: 10px;" size="small" type="success" @click="abortMultipartUpload">清除切片</el-button>
 </el-upload>
 <el-progress :percentage="percentage" :status="uploadStatus"></el-progress>
 </div>
</template>

<script>
 let OSS = require('ali-oss') // 引入ali-oss插件
 const client = new OSS({
 region: 'oss-cn-shanghai',//根據那你的Bucket地點來填寫
 accessKeyId: 'LTA*********RaXY',//自己賬戶的accessKeyId
 accessKeySecret: 'uu1************GiS',//自己賬戶的accessKeySecret
 bucket: 'a******o',//bucket名字
 });
export default {
 data () {
 return {
  fileList:[],
  file: null,
  tempCheckpoint: null, // 用來緩存當前切片內容
  uploadId: '',
  uploadStatus: null, // 進度條上傳狀態
  percentage: 0, // 進度條百分比
  uploadName: '', //Object所在Bucket的完整路徑
 }
 },
 mounted() {
 // window.addEventListener('online', this.resumeUpload);
 },
 methods: {
 // 點擊上傳至服務器
 submitForm(file) {
  this.multipartUpload();
 },
 // 取消分片上傳事件
 async abortMultipartUpload() {
  window.removeEventListener('online', this.resumeUpload)
  const name = this.uploadName; // Object所在Bucket的完整路徑。
  const uploadId = this.upload; // 分片上傳uploadId。
  const result = await client.abortMultipartUpload(name, uploadId);
  console.log(result, '=======清除切片====');
 },
 // 暫停分片上傳。
 stopUplosd () {
  window.removeEventListener('online', this.resumeUpload) // 暫停時清除時間監聽
  let result = client.cancel();
  console.log( result, '---------暫停上傳-----------')
 },
 // 切片上傳
 async multipartUpload () {
  if (!this.file) {
  this.$message.error('請選擇文件')
  return
  }
  this.uploadStatus = null
  // console.log("this.uploadStatus",this.file, this.uploadStatus);

  this.percentage = 0
  try {
  //object-name可以自定義為文件名(例如file.txt)或目錄(例如abc/test/file.txt)的形式,實現將文件上傳至當前Bucket或Bucket下的指定目錄。
  let result = await client.multipartUpload(this.file.name, this.file, {
   headers: {
   'Content-Disposition': 'inline',
   'Content-Type': this.file.type //註意:根據圖片或者文件的後綴來設置,我試驗用的‘.png'的圖片,具體為什麼下文解釋
   },
   progress: (p, checkpoint) => {
   this.tempCheckpoint = checkpoint;
   this.upload = checkpoint.uploadId
   this.uploadName = checkpoint.name
   this.percentage = p * 100
   // console.log(p, checkpoint, this.percentage, '---------uploadId-----------')
   // 斷點記錄點。瀏覽器重啟後無法直接繼續上傳,您需要手動觸發上傳操作。
   },
   meta: { year: 2020, people: 'dev' },
   mime: this.file.type
  });
  console.log(result, this.percentage, 'result= 切片上傳完畢=');
  } catch (e) {
  window.addEventListener('online', this.resumeUpload) // 該監聽放在斷網的異常處理
  // 捕獲超時異常。
  if (e.code === 'ConnectionTimeoutError') { // 請求超時異常處理
   this.uploadStatus = 'exception'
   console.log("TimeoutError");
   // do ConnectionTimeoutError operation
  }
  // console.log(e)
  }
 },
 // 恢復上傳。
 async resumeUpload () {
  window.removeEventListener('online', this.resumeUpload)
  if (!this.tempCheckpoint) {
  this.$message.error('請先上傳')
  return
  }
  this.uploadStatus = null
  try {
  let result = await client.multipartUpload(this.file.name, this.file, {
   headers: {
   'Content-Disposition': 'inline',
   'Content-Type': this.file.type //註意:根據圖片或者文件的後綴來設置,我試驗用的‘.png'的圖片,具體為什麼下文解釋
   },

   progress: (p, checkpoint) => {
   this.percentage = p * 100
   console.log(p, checkpoint, 'checkpoint----恢復上傳的切片信息-------')
   this.tempCheckpoint = checkpoint;
   },
   checkpoint: this.tempCheckpoint,
   meta: { year: 2020, people: 'dev' },
   mime: this.file.type
  })
  console.log(result, 'result-=-=-恢復上傳完畢')
  } catch (e) {
  console.log(e, 'e-=-=-');
  }
 },

 // 選擇文件發生改變
 handleChange(file, fileList) {
  this.fileList = fileList.filter(row => row.uid == file.uid)
  this.file = file.raw
  // 文件改變時上傳
  // this.submitForm(file)
 },
 handleRemove(file, fileList) {
  this.percentage = 0 //進度條置空
  this.fileList = []
 },
 }
}
</script>

<style scoped>
</style>

如果相關依賴已經安裝完畢,但是上述代碼操作時仍有報錯,請檢查以下問題

 const client = new OSS({
 region: 'oss-cn-shanghai',//根據那你的Bucket地點來填寫
 accessKeyId: 'LT******XY',//自己賬戶的accessKeyId
 accessKeySecret: 'uu*********GiS',//自己賬戶的accessKeySecret
 bucket: 'a******io',//bucket名字
 });

上述信息放在前端會存在安全問題,如在項目中使用盡量由後端接口提供。或使用STS臨時授權。demo中沒有,請自行探索。
https://www.alibabacloud.com/help/zh/doc-detail/100624.htm?spm=a2c63.p38356.879954.5.7a234d04IQpf5I#concept-xzh-nzk-2gb

配置項中信息可以問後端或者運維,bucket的名字必須是你OSS上存在的且你有權限訪問的,不然會一直報 Pleasr create a busket first或者一直報跨域

當遇到跨域時,或者遇到報報錯信息中有etag時,請檢查OSS配置,然後找有OSS服務器權限人員進行配置:

window.addEventListener('online', this.resumeUpload)用於監聽網絡狀態(斷網狀態和連網狀態),實現斷網後恢復網絡自動上傳就必須設置監聽。

window.removeEventListener('online', this.resumeUpload)取消監聽。如果不設置取消監聽,聯網狀態下會一直處於進行上傳,因為一直滿足監聽條件`

headers: {
   'Content-Disposition': 'inline',
   'Content-Type': this.file.type //註意:根據圖片或者文件的後綴來設置,我取得是文件的type,具體為什麼下文解釋
   },

‘Content-Type’: this.file.type`的作用:加瞭在文件上傳完畢後,訪問文件鏈接時可以直接查看,否則會直接下載。

文件上傳完畢後查看,可以去resule.res.requestUrls中去取,但是註意要去點地址後面的 ?uploadId=******

上述代碼隻是demo,代碼以實現功能為主,並不嚴謹,請自行完善。

到此這篇關於vue+element+oss實現前端分片上傳和斷點續傳的文章就介紹到這瞭,更多相關vue 分片上傳和斷點續傳內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!