使用vue 结合 腾讯cos实现上传图片
cos
cos客户端:https://cloud.tencent.com/document/product/436/11366
cos入门:https://cloud.tencent.com/document/product/436/11459
借鉴:https://www.jb51.net/article/161251.htm
js代码
- 安装依赖包
npm install cos-js-sdk-v5
- 使用 axios 来请求接口
- 代码 封装 cos.js 文件
import CosCloud from "cos-js-sdk-v5"
import axios from 'axios'
// 上传文件(调用相关api putObject来上传文件)
/**
* @method uploadFile
* @param {object} cos
*/
function uploadFile(cos, file, signInfo, callback) {
// name: 图片的名称,可以自定义,这里为了不覆盖相同名照片,使用了时间戳
let name = `/store/st/${new Date().valueOf()}`
let pic = ''
// Bucket: 存储桶 Bucket 的名称,命名规则为 BucketName-APPID,此处填写的存储桶名称必须为此格式
// Region:Bucket 所在地域,枚举值请参阅 地域和访问域名:https://cloud.tencent.com/document/product/436/6224
cos.putObject(
{
Bucket: 'marryparty-1253457213',
Region: 'ap-guangzhou',
Key: `${name}`,
Dir: 'store',
Body: file,
onHashProgress: function (progressData) {
console.log('校验中', JSON.stringify(progressData));
},
onProgress: function (progressData) {
console.log('上传中', progressData)
if (progressData.percent === 1) {
// 上传完执行操作 这里将图片的 pic 作为图片的src 抛出去,在调用的地方用res.pic获取即可
pic = `http://marryparty-1253457213.cos.ap-guangzhou.myqcloud.com${name}`
}
},
},
function (err, data) {
console.log(data)
if (err) {
callback({ success: false, msg: '文件上传失败!' });
return;
}
// 上传成功把数据抛出去, pic 是上文的图片的链接
callback({ success: true, msg: '上传成功!', data: data, signInfo: signInfo, pic: pic });
}
)
}
// 获取文件上传密钥(最好存在后端通过ajax请求获取,安全性较高)
function getFileToken(Vue, fileInfo, cos, file, uploadStatusCallbalck) {
// 秘钥是请求后台的接口,替换即可
// 正式环境会自动加域名
let url = '/manage/store-api/get_ticket'
// 本地
// let url = 'https://store.ihuyue.cn/manage/store-api/get_ticket'
if (!file) return;
// 异步获取临时密钥
axios
.get(url)
.then(function (res) {
if (res.data.ret == 0) {
//获取的临时秘钥存储在vuex中
Vue.$store.commit('setUPDATEFILEINFO', res.data.data);
uploadFile(cos, file, res.data.data, uploadStatusCallbalck);
} else {
uploadStatusCallbalck({ success: false, msg: '获取文件秘钥失败!' });
}
})
.catch(function (err) {
uploadStatusCallbalck({ success: false, msg: '获取文件秘钥接口出错!' });
});
}
/**
* 初始化上传文件对象
* @param {object} Vue
* @param {string} fileName 文件名
* @param {object} file 上传的文件流及文件类型 名称相关信息
* @param {Array} 允许上传的文件类型
* @param {function} uploadStatusCallbalck
* @return {function} 返回回调函数
*/
export const initUploadObj = function (Vue, fileName, file, type, uploadStatusCallbalck) {
let fileInfo = {
file_name: fileName,
media_type: 2,
media_sub_type: 0,
size_of_bytes: 122,
file_expired_type: 'permanent',
};
console.log(file, 'file---------')
// 上传图片大小做限制
if (file.size > 2048) {
Vue.$Message.error('请上传小于2M的图片!')
return
}
//前端做文件类型限制
if (type == 'image') {
type = ['.jpg', '.gif', '.jpeg', '.bmp', '.png']
}
if (type == 'excel') {
type = ['.xlsx']
}
let fileType = file.name ? file.name.substring(file.name.lastIndexOf(".")).toLowerCase() : '';
if (!!type && type.indexOf(fileType) < 0) {
uploadStatusCallbalck({ success: false, msg: '请上传正确的' + type + '文件格式!' })
return
}
var cos = new CosCloud({
getAuthorization: function (options, callback) {
let singleInfo = Vue.$store.state.app.fileToken;
callback({
TmpSecretId: singleInfo.credentials.tmpSecretId,
TmpSecretKey: singleInfo.credentials.tmpSecretKey,
XCosSecurityToken: singleInfo.credentials.sessionToken,
ExpiredTime: singleInfo.expiredTime,
});
},
});
fileInfo.file_name = file.name
//获取文件上传密钥
getFileToken(Vue, fileInfo, cos, file, uploadStatusCallbalck);
}
export default initUploadObj
使用
- html 这里只上传一张图片,可以根据自己需要修改
<div class="l-pic">
<div v-if="formValidate.header" class="upload-img">
<img class="up-img" :src="formValidate.header">
<div class="up-change">
<div>修改头像</div>
<input class="up-input" type="file" id="file" @change="uploadImg()" />
</div>
</div>
<div v-else class="up-block">
<Icon type="ios-add" size="25" />
<input class="up-input" type="file" id="file" @change="uploadImg()" />
</div>
<div class="msg">上传图片的宽高比必须满足1:1,否则无法上传!建议图片尺寸为130 * 130。(最大不超过2M)</div>
</div>
- 这里把css也贴出来,方便看效果
.l-pic {
width: 100%;
display: flex;
.upload-img {
position: relative;
height: 100px;
.up-img {
width: 100px;
height: 100px;
}
.up-change {
position: absolute;
bottom: 0;
left: 0;
width: 100px;
height: 20px;
line-height: 20px;
text-align: center;
color: #fff;
background: rgba(0, 0, 0, .4);
.up-input {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
outline: none;
opacity: 0;
z-index: 3;
}
}
}
.up-block {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 100px;
height: 100px;
border: 1px dashed #ccc;
.up-input {
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
outline: none;
opacity: 0;
z-index: 3;
}
}
.msg {
color: rgb(45, 140, 240);
margin-left: 10px;
}
}
- js
import initUploadObj from '@/libs/cos'
uploadImg() {
let that = this
let file = document.querySelector('input[type=file]').files[0]
let type = file.type
//初始化文件上传
initUploadObj(that, file.name, file, 'image', function(res) {
if (res.success) {
// 这里res是cos里返回的数据
console.log(res.pic)
// 上传图片比例限制
let img = new Image()
img.src = res.pic
img.onload = function(){
let w = img.width
let h = img.height
if (w != h) {
that.$Message.error('请按照规定的宽高比上传图片!')
return
} else {
that.formValidate.header = res.pic
that.formValidate = JSON.parse(JSON.stringify(that.formValidate))
}
}
} else {
this.$Message.error('图片上传失败')
}
})
},
网友评论