純前端實現: 切片上傳
斷點續傳
。斷點續傳
需要在切上上傳的基礎上實現
前端之前上傳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,程式碼以實現功能為主,並不嚴謹,請自行完善。如對各位有所幫助,請推薦,謝謝各位!。
以上就是全部內容,如有疑問,敬請留言!如有問題,請指出,謝謝~~