目标:
Understand mainstream image storage solutions and upload processes
plan description
plan |
Scenes |
Is it mainstream |
Store in your company's ordinary server |
Simple scene with few pictures |
no |
Stored in a third-party cloud server |
A large number of pictures and videos, etc., and additional functions are required, such as watermark processing, video review, etc. (professional people do professional things) Qiniu Cloud/Tencent Cloud/Alibaba Cloud |
yes |
The actual resource of the picture will be stored in the third-party cloud server, and our own database will store a valid picture url address
Flow Description
If we upload the picture to the cloud server, what is the upload process like? The method of uploading pictures at the backend is more versatile, because it is easier to control the unified control of the backend by designing some security strategies such as secret key control when transmitting pictures.
Tencent cloud cos application configuration
Goal: Create a free cloud storage using off-the-shelf Tencent Cloud services
1. Create an account for real-name authentication
Here you need to fill in your real name information, rest assured to write, will not leak
2. Create a bucket
3. Set cors rules
Here, because we are testing the upload, all uploads are allowed. The real production environment needs to configure the specific domain name and operation method separately.
4. Key Configuration Instructions
The server is personal and requires certain permissions to upload pictures freely. The person responsible for permission verification is actually the secret key, which means that having the secret key is a necessary condition for uploading
Key configuration
security tips
In actual work, the secret key is sensitive information and cannot be directly stored in the front-end, which is prone to security problems. A better approach is to hand over the secret key to the back-end management. The front-end obtains the secret key by calling the interface first. After having the secret key Then upload
We have completed the above, all the preparations~
5. Upload component - basic package
Goal: Encapsulate a common upload component for use by business components
Understand the requirements and create a new upload component
understand needs
Goal: The employee profile picture and other names and mobile phone numbers are several fields that are juxtaposed. These fields will need to be submitted to the backend through the interface in the future
Select a picture through the upload component and upload the picture to the cloud server The cloud service returns us a valid picture url
Create a new public upload component
Our upload function is based on the secondary development of the element upload component, first prepare the elementUI upload component we need, and select a suitable sample code according to our specific business needs
Custom upload configuration
Key attribute: :http-request="upload" action="#"
Use custom behavior to override the default upload, note that once the custom upload behavior is set, all upload operations need to be implemented by yourself, such as data processing, after uploading successfully Subsequent operations, the on-success hook function will not continue to trigger
<template>
<div>
<el-upload
class="avatar-uploader"
action="#"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
:http-request="upload"
>
<img v-if="imageUrl" :src="imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon" />
</el-upload>
</div>
</template>
<script>
export default {
data() {
return {
imageUrl: ''
}
},
methods: {
// 回调函数 自定义上传逻辑 适合不能直接上传给自己的服务器 需要一些自定义写法上传三方 加上这个之后 组件只负责图片校验 上传部分不管了
upload(file) {
console.log(file)
},
// 上传完毕自动执行 添加:http-request后 当前函数失效
handleAvatarSuccess(res, file) {
this.imageUrl = URL.createObjectURL(file.raw)
},
// 上传前自动效验 校验通过执行
beforeAvatarUpload(file) {
const isPNG = file.type === 'image/png'
const isLt2M = file.size / 1024 / 1024 < 2
if (!isPNG) {
this.$message.error('上传头像图片只能是 PNG 格式!')
}
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 2MB!')
}
return isPNG && isLt2M
}
}
}
</script>
<style>
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409eff;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
</style>
Implement upload and echo
Realize the upload function according to the upload API of cos
Tencent cloud document address https://cloud.tencent.com/document/product/436/35649#.E7.AE.80.E5.8D.95.E4.B8.8A.E4 .BC.A0.E5.AF.B9.E8.B1.A1
1- Install sdk file
npm i cos-js-sdk-v5
2- Introduce Cos and instantiate the cos object
Note: This can only be used as a test to avoid directly exposing the key id in the js code.
If the front-end is still leading the upload during actual development, the correct process is as follows:
1. The front-end needs to call a back-end interface of our own to obtain A temporary secret key [will expire in a short time]
2 Pass in the obtained temporary secret key to instantiate a cos object
3 Send data as you want
// 引入必要的COS模块
const COS = require('cos-js-sdk-v5')
// 实例化对象
const cos = new COS({
SecretId: 'xxxx', // 身份识别ID
SecretKey: 'xxxx' // 身份秘钥
})
3- Use the cos object to complete the upload
object storage upload object-SDK Documentation-Documentation Center-Tencent Cloud
upload({file}) {
if (file) {
// 执行上传操作
cos.putObject({
Bucket: 'xxxxxx', /* 存储桶 */
Region: 'xxxx', /* 存储桶所在地域,必须字段 */
Key: file.name, /* 文件名 */
StorageClass: 'STANDARD', // 上传模式, 标准模式
Body: file, // 上传文件对象
onProgress: (progressData) => {
console.log(JSON.stringify(progressData))
}
}, (err, data) => {
console.log(err || data)
// 上传成功之后
if (data.statusCode === 200) {
this.imageUrl = `https:${data.Location}`
}
})
}
}
6. Upload component - business use
任务:
Use the parent-child communication mode to realize image upload echo
1- Realize the submission of url to the database [from child to parent]
// 子组件
if (data.statusCode === 200) {
this.imageUrl = `https://${data.Location}`
// 执行这个自定义事件把url传出去
this.$emit('get-url', this.imageUrl)
}
// 父组件
<upload-img @get-url="getUrl" />
getUrl(url) {
console.log(url)
// 图片上传完毕之后 用于提交给后端的字段里就有了有效的url
this.userInfo.staffPhoto = url
}
2- Refresh and backfill the image url [ father to son + watch synchronization ]
// 父组件
<upload-img :url="userInfo.staffPhoto" @get-url="getUrl" />
// 子组件
props: {
url: {
type: String,
default: ''
}
},
watch: {
url: function() {
this.imageUrl = this.url
}
}