本实例展示如何使用go语言及其优秀框架gin做后端,Vue及前端框架elmentUI做前端上传逻辑及界面,以及使用阿里云oss存储上传的视频或文件。
1、使用工具
后端:Go语言,gin框架
前端:Vue,ElmentUI
云存储:阿里云OSS
开发IDE:Goland
操作系统:Ubuntu
2、配置及路由
2.1, 项目目录下新建.env配置文件,写入服务端口、数据库等配置
PORT="9900"
OSS_ENDPOINT="oss-cn-hongkong.aliyuncs.com"
OSS_ACCESS_KEY_ID="LTAI4FrhMxuNSQr********"
OSS_ACCESS_SECRET="HvREwCWrK0rwpFAPu1********"
OSS_BUCKET="l******"
2.2, 引入gin框架,并设置路由:项目根目录下创建routers.go,写入代码:
package main
import (
"github.com/gin-gonic/gin"
)
func CollectRoute(r *gin.Engine) *gin.Engine {
r.POST("upload/token", controller.UploadToken)
return r
}
2.3, 项目根目录下main.go编写
package main
import (
"github.com/gin-gonic/gin"
)
func main(){
// gin框架启动
r := gin.Default()
r = CollectRoute(r)
// 配置文件读取端口
port := os.Getenv("PORT")
if port != ""{
panic(r.Run(":"+port))
}
panic(r.Run())
}
2.4, 上传controller编写
// 创建controller/upload.go
package controller
import (
"github.com/gin-gonic/gin"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"github.com/google/uuid"
"net/url"
"os"
)
// 阿里云oss token 获取
func UploadToken(ctx *gin.Context) {
client,err:=oss.New(os.Getenv("OSS_ENDPOINT"),os.Getenv("OSS_ACCESS_KEY_ID"),os.Getenv("OSS_ACCESS_SECRET"))
if err!=nil{
return ctx.JSON(http.StatusBadGateway,gin.H{"code":502,"msg":"OSS请求错误",err:err.Error()})
}
// 获取存储空间
bucket,err:=client.Bucket(os.Getenv("OSS_BUCKET"))
if err!=nil{
return ctx.JSON(http.StatusBadGateway,gin.H{"code":502,"msg":"OSS请求错误",err:err.Error()})
}
// 带可选参数的签名直传
options:=[]oss.Option{
oss.ContentType("image/png"),
}
// 拼接上传图片的路径信息
key:="upload/avatar/"+uuid.Must(uuid.NewRandom()).String()+".png"
// 获取上传put地址
signedPutUrl,err:=bucket.SignURL(key,oss.HTTPPut,600,options...)
if err!=nil{
return ctx.JSON(http.StatusBadGateway,gin.H{"code":502,"msg":"OSS bucket错误",err:err.Error()})
}
// 获取已上传的预览地址
signedGetUrl,err:=bucket.SignURL(key,oss.HTTPGet,600)
if err!=nil{
return ctx.JSON(http.StatusBadGateway,gin.H{"code":502,"msg":"OSS bucket错误",err:err.Error()})
}
putUrl,_:=url.QueryUnescape(signedPutUrl)
getUrl,_:=url.QueryUnescape(signedGetUrl)
return ctx.JSON(http.StatusOK,gin.H{"key":key,"put":putUrl,"get":getUrl})
}
3、前端编写
//安装element
vue add element
3.1 upload Token请求API逻辑编写
// 创建src\api\upload\index.js
import axios from 'axios'
// 服务端URL
const URI = 'http://192.168.30.162:3000';
// 获取图片Token
const postUploadToken = fileName => axios.post(URI+'/upload/token',{filename:fileName}).then(res=>res.data);
export default postUploadToken;
3.2 上传页面搭建
<template>
<div class="post-video">
<h2>欢迎投稿</h2>
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="封面上传">
<el-upload
class="avatar-uploader"
label="视频封面"
action=""
ref="upload"
:show-file-list="false"
:before-upload="fnBeforeUpload"
:http-request="fnHttpRequest">
<img v-if="imageUrl" :src="imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
<div class="el-uploader-tip" slot="tip">只能上传500kb内的png图片</div>
</el-upload>
</el-form-item>
</el-form>
</div>
</template>
<script>
import uploadAPI from '@/api/upload/'
export default {
name: "PostImg",
data(){
return {
imageUrl:'',
}
},
methods:{
// 上传之前判断
fnBeforeUpload(file){
const isPNG = file.type === "image/png",
isLt2M = file.size /1024 < 900;
if(!isPNG){
this.$message.error("上传头像只能png")
}
if(!isLt2M){
this.$message.error("上传图片需要小于500KB")
}
return isPNG && isLt2M
},
// 上传图片到
fnHttpRequest(option){
uploadAPI(option.file.name).then((res)=>{
const req = new XMLHttpRequest();
req.open('PUT',res.data.put,true);
req.send(option.file);
req.onload=()=>{
this.imageUrl = res.data.get;
}
}).catch((error)=>{
this.$notify.error({
title:"网络错误",
message:error
})
})
}
}
}
</script>
<style scoped>
.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>
最新回复