1.导入依赖
yarn cos-js-sdk-v5
或
npm i cos-js-sdk-v5
2.引入文件
import apis from '@/api'//自定义接口文件
import stroage from './stroage'//据项目而定,此处避免在未过期时重复请求,所以手动存储了时间参数
import uuid from './uuid'//据项目而定,防止文件重名故引入
import COS from 'cos-js-sdk-v5'
import { Message } from 'element-ui'
import batchDownZip from './batchDownZip'//批量下载,下方有备注来源
import { hideLoading } from './loading'//自行封装Element.hideloading
const Stroage = stroage
var Bucket =
import.meta.env.VITE_BUCKET
var Region =
import.meta.env.VITE_REGION
上面用到的stroage.js
文件
function isJSON(str) {
if (typeof str == 'string') {
try {
var obj = JSON.parse(str);
if (typeof obj == 'object' && obj) {
return true;
} else {
return false;
}
} catch (e) {
// console.log('isJSON-error:' + str + '!!!' + e);
return false;
}
}
}
export default Storage = {
get(name) {
let data = localStorage.getItem(name)
return isJSON(data) ? JSON.parse(data) : data
},
set(prop, value) {
localStorage.setItem(prop, isJSON(value) ? value : JSON.stringify(value))
},
remove(name) {
localStorage.removeItem(name)
}
}
上面用到的uuid.js
文件
export default function uuid() {
var temp_url = URL.createObjectURL(new Blob());
var uuid = temp_url.toString(); // blob:https://xxx.com/b250d159-e1b6-4a87-9002-885d90033be3
URL.revokeObjectURL(temp_url);
return uuid.substr(uuid.lastIndexOf("/") + 1);
}
3.获取cos鉴权
async function getCosParams(type) {
try {
const cosBeforeTime = Storage.get(`cosBeforeTime_${type}`) || 0
const nowTime = Date.parse(new Date())
let data = Stroage.get(`cosParams_${type}`) || {}
const isTimeOut = nowTime - cosBeforeTime >= 10 * 29 * 1000
function createCos(data, type) {
Stroage.set(`cosParams_${type}`, data)
return new COS({
getAuthorization: function(options, callback) {
callback({
TmpSecretId: data.credentials.tmpSecretId,
TmpSecretKey: data.credentials.tmpSecretKey,
XCosSecurityToken: data.credentials.sessionToken,
StartTime: data.startTime, // 时间戳,单位秒,如:1580000000,建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
ExpiredTime: data.expiredTime // 时间戳,单位秒,如:1580000900
})
}
})
}
if (type.includes('down')) {
if (isTimeOut || !Object.keys(data).length) {
Stroage.set(`cosBeforeTime_${type}`, nowTime)
data = await apis.getCos_download()
}
return createCos(data, type)
} else {
// 避免上传过期
Stroage.set(`cosBeforeTime_${type}`, nowTime)
data = await apis.getCos_upload()
return createCos(data, type)
}
} catch (err) {
return Promise.reject(err)
}
}
4.下载加密文件
/**
*
* @path {string} 路径
* @callback {function} 回调
* @compress {boolean} 是否压缩
* @fail {boolean} 失败回调
* @returns
*/
async function cosDown(path, callback, compress, fail) {
try {
if (path) {
const cos = await getCosParams('download')
cos.getObjectUrl({
Bucket /* 填入您自己的存储桶,必须字段 */ ,
Region /* 存储桶所在地域,例如ap-beijing,必须字段 */ ,
Key: path /* 存储在桶里的对象键(例如1.jpg,a/b/test.txt),必须字段 */ ,
Sign: true /* 获取带签名的对象URL */
}, (err, data) => {
if (err) {
console.error(err, '下载失败')
} else {
const url = `${data.Url}${compress ? '&imageMogr2/format/webp' : ''}`
const downUrl = data.Url + (data.Url.indexOf('?') > -1 ? '&' : '?') + 'response-content-disposition=attachment'
callback && callback({ url, downUrl})//据项目需求定
}
})
} else {
return 'path os undefined'
}
} catch (err) {
fail && fail(e)
hideLoading()
return Promise.reject(err)
}
}
5.批量下载
下面用到的批量下载方法batchDownZip
详见文章 js关于base64文件的处理以及下载
async function cosBatchDown(e) {
try {
const { bodyType, id, callback } = e
const res = await apis.DownLoadMotion(bodyType, id)
const { paths, name } = res
const files = []
paths.map((i, n) => {
cosDown(i, (urls) => {
files.push({ name: i, url: urls.downUrl })
if (n == paths.length - 1) {
batchDownZip(files, name, callback)
}
}, true)
})
} catch (err) {
return Promise.reject(err)
}
}
6.普通上传
/**
* 普通上传
* @file {file} file
* @callback {function} 回调
* @name {string} 文件名
* @fail {function} 失败回调
*/
function cosUpload(file, callback, name = null, fail) {
getCosParams('upload').then(cos => {
let fileType = Object.prototype.toString.call(file);
cos.putObject({
Bucket: Bucket,
Region: Region,
Key: name ? uuid() + name : uuid() + file.name.slice(file.name.lastIndexOf('.')).toLocaleLowerCase(),
Body: fileType == '[object File]' ? file : file.blob || file,
onHashProgress: function(progressData) {},
onProgress: function(progressData) {
// console.log('上传中', JSON.stringify(progressData))
}
},
function(err, data) {
// console.log(err, data, 'cosUpload上传结果')
if (err) {
fail && fail(err)
hideLoading()
Message({
message: err || 'cos上传失败',
type: 'error',
duration: 3 * 1000
})
console.error('cos上传失败', err, file)
} else {
// console.log('cos上传成功', file)
const { Location } = data
callback && callback(Location.slice(Location.indexOf('/') + 1))//据项目需求定
}
}
)
}).catch((err) => {
fail && fail(err)
hideLoading()
Message({
message: err || 'cos上传失败',
type: 'error',
duration: 3 * 1000
})
console.error('cosUpload-getCosParams', err)
})
}
7.分片传输
function cosUpload(file, callback, name = null, fail) {
getCosParams('upload').then(cos => {
let fileType = Object.prototype.toString.call(file);
cos.uploadFile({
Bucket: Bucket,
Region: Region,
Key: name ? uuid() + name : uuid() + file.name.slice(file.name.lastIndexOf('.')).toLocaleLowerCase(),
Body: fileType == '[object File]' ? file : file.blob || file,
SliceSize: 1024 * 1024 * 5,
/* 触发分块上传的阈值,超过5MB使用分块上传,非必须 */
// onHashProgress: function(progressData) {
// // console.log('校验中', JSON.stringify(progressData))
// },
// onProgress: function(progressData) {
// // console.log('上传中', JSON.stringify(progressData))
// }
},
function(err, data) {
console.log(err, data, 'cosUpload上传结果')
if (err) {
fail && fail(err)
hideLoading()
Message({
message: err || 'cos上传失败',
type: 'error',
duration: 3 * 1000
})
console.log('cos上传失败', err, file)
} else {
// console.log('cos上传成功', file)
const { Location } = data
callback && callback(Location.slice(Location.indexOf('/') + 1))
}
}
)
})
}