前端使用cos阿里云对文件进行加密上传与下载

本文详细介绍了如何在前端使用阿里云Cos进行文件的加密上传、下载操作,包括依赖导入、鉴权获取、加密下载、批量下载、普通上传和分片传输的步骤。
摘要由CSDN通过智能技术生成

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))
                }
            }
        )
    })
}
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值