Vue项目中腾讯云文件上传

简介

文件上传一般是前端将文件通过form表单或者ajax提交给后端

这里介绍前端直接上传文件到腾讯云的对象存储中

小文件直接上传,大文件用分片上传的方式。

文件分片上传需要一个识别文件的唯一标识。而md5是非常合适的,前端在文件上传前在本地使用spark-md5计算md5

准备

  • 注册腾讯云账号
  • COS对象存储控制台创建存储桶,得到Bucket(存储桶名称)和Region(地域名称)
  • 控制台密钥管理获取项目的SecretIdSecretKey

步骤

安装

  • 安装:npm i cos-js-sdk-v5 spark-md5 --save

使用

  • config/dev.env.jsconfig/prod.env.js文件中添加相关配置
module.exports = { // ... Bucket: '"xxx-xxx-xxx"', // Bucket Region: '"ap-beijing"', // Region Domain:'"xxx.xxx.com"', // Domain }
  • src/utils/目录下新建文件uploadfile.js
import COS from 'cos-js-sdk-v5' import SparkMD5 from 'spark-md5' import { getCOSAuth } from '@/axios/api' var key = '' // 配置 const cosConfig = { Bucket: process.env.Bucket, Region: process.env.Region, Domain: process.env.Domain } // 初始化实例 var cos = new COS({ getAuthorization: async function(options, callback) { /** * 签名计算放在前端会暴露 SecretId 和 SecretKey * 我们把签名计算过程放在后端实现,前端通过 ajax 向后端获取签名结果 * 正式部署时请再后端加一层自己网站本身的权限检验。 * 异步获取临时密钥 */ const res = await getCOSAuth() const authdata = res.data.response const auth = { TmpSecretId: authdata.credentials.tmpSecretId, TmpSecretKey: authdata.credentials.tmpSecretKey, XCosSecurityToken: authdata.credentials.sessionToken, ExpiredTime: authdata.expiredTime // 在ExpiredTime时间前,不会再次调用getAuthorization } callback(auth) }, FileParallelLimit: 3, // 文件并发数 ChunkParallelLimit: 8, // 同一个上传文件的分块并发数 ChunkSize: 1024 * 1024 * 8 // 分块上传时,每块的字节数大小 }) // 获取cos存储的图片地址,替换为域名地址 function getObjectUrl() { const url = cos.getObjectUrl({ Bucket: cosConfig.Bucket, Region: cosConfig.Region, Key: key, Sign: false }, function(err, data) { // console.log(err || data) }) // 腾讯云的地址替换为域名地址 const p = `${cosConfig.Bucket}.cos.${cosConfig.Region}.myqcloud.com` return url.replace(p, cosConfig.Domain) } // 获得文件md5 function getFileMD5(file, callback) { // 声明必要的变量 const fileReader = new FileReader() // 文件每块分割2M,计算分割详情 const chunkSize = 2 * 1024 * 1024; const chunks = Math.ceil(file.size / chunkSize) let currentChunk = 0 // 创建md5对象(基于SparkMD5) const spark = new SparkMD5() // 每块文件读取完毕之后的处理 fileReader.onload = function(e) { // 每块交由sparkMD5进行计算 spark.appendBinary(e.target.result) currentChunk++ // 如果文件处理完成计算MD5,如果还有分片继续处理 if (currentChunk < chunks) { loadNext() } else { callback(spark.end()) } } // 处理单片文件的上传 function loadNext() { const start = currentChunk * chunkSize const end = start + chunkSize >= file.size ? file.size : start + chunkSize fileReader.readAsBinaryString(file.slice(start, end)) } loadNext() } // 大文件分片上传-通过sliceUploadFile上传 export function uploadFile(file, callback, progressBc) { // 得到md5码 getFileMD5(file, md5 => { // 存储文件的md5码 file.md5 = md5 const subfix = file.name.substr(file.name.lastIndexOf('.')) key = file.md5 + subfix; cos.sliceUploadFile({ Bucket: cosConfig.Bucket, Region: cosConfig.Region, Key: key, Body: file, onProgress: function(progressData) { progressBc(progressData.percent) } }, function(err, data) { if (err) { callback(err) } else { data.fid = getObjectUrl() callback(null, data) } }) }) } // 小文件直接上传-通过putObject上传 export function uploadFile2(file, callback, progressBc) { // 得到md5码 getFileMD5(file, md5 => { // 存储文件的md5码 file.md5 = md5 const subfix = file.name.substr(file.name.lastIndexOf('.')) key = file.md5 + subfix cos.headObject({ Bucket: cosConfig.Bucket, Region: cosConfig.Region, Key: key }, function(err, data) { if (err != null) { cos.putObject({ Bucket: cosConfig.Bucket, Region: cosConfig.Region, Key: key, Body: file, onProgress: function(progressData) { // console.log(JSON.stringify(info)) progressBc(progressData.percent) } }, (err, data) => { if (err && err.error) { // wx.showModal({ title: '返回错误', content: '请求失败:' + err.error.Message + ';状态码:' + err.statusCode, showCancel: false }); } else if (err) { // wx.showModal({ title: '请求出错', content: '请求出错:' + err + ';状态码:' + err.statusCode, showCancel: false }); } else { callback(key) // wx.showToast({ title: '上传成功', icon: 'success', duration: 3000 }); } }) } else if (data != null) { callback(key) } }) }) }
  • 组件中使用
import { uploadFile } from '@/utils/uploadfile' export default { mounted() { document.getElementById('file-selector').onchange = function () { var file = this.files[0] if (!file) return this.cosUploadFile(file) } }, methods: { // 通过腾讯云 cos-js-sdk-v5 上传 cosUploadFile(file) { const that = this uploadFile(file, (err, data) => { if (err) { console.log(err) } else { that.$emit('getUploadFiles', data) } }) } } }

参考链接


创作不易,若本文对你有帮助,欢迎打赏支持作者!

 分享给好友: