vue前端上传文件minio服务器简单示例(go后端)
vue
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
项目地址:https://gitcode.com/gh_mirrors/vu/vue
免费下载资源
·
前端代码:
文件上传按钮及样式
<template>
<div>
<el-button class="file-box" text>
<input type="file" multiple class="file-btn"
required @change="handleFileChange" />上传
</el-button>
</div>
</template>
<style>
.file-box {
display: inline-block;
position: relative;
overflow: hidden;
color: rgb(252, 113, 0);
background-color: rgb(255, 255, 255);
}
.file-btn {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
outline: none;
filter: alpha(opacity=0);
-moz-opacity: 0;
-khtml-opacity: 0;
opacity: 0;
}
</style>
添加上传方法,生成uploadid:
//生成uploadid
async handleFileChange(e) {
this.file = e.target.files[0];
const data = {
bucket_name: this.bucket_name, //桶名
object_name: this.file.name //文件名
};
//upload_addr后端地址
let res = await func.post(this.upload_addr
+ '/new_multipart_upload', data);
this.upload_id = res.data.data;
//初始化上传进度,upload_progress是一个map
this.upload_progress.set(this.upload_id, 0);
this.uploadFile();
},
分片,生成分片上传URL:
async uploadFile() {
if (!this.file) {
alert('请选择文件');
return;
}
const totalChunks = Math.ceil(this.file.size / this.chunkSize);
for (let chunk = 0; chunk < totalChunks; chunk++) {
const start = chunk * this.chunkSize;
const end = Math.min(this.file.size, start + this.chunkSize);
const chunkFile = this.file.slice(start, end);
let part_num = chunk + 1;
const data = {
bucket_name: this.bucket_name,
object_name: this.file.name,
upload_id: this.upload_id,
part_num: part_num
};
// 为每个分片生成上传URL
let res = await func.post(this.upload_addr + '/presign',
data);
let url = res.data.data;
try {
await this.uploadChunk(chunkFile, url,
part_num, totalChunks);
} catch (error) {
console.error(error);
}
}
},
上传分片:
async uploadChunk(file, url, part_num, totalChunks) {
fetch(url, {
method: 'PUT',
body: file
})
.then((response) => {
console.log(`${part_num} 上传成功`, response);
let sum = this.upload_progress.get(this.upload_id) + 1;
this.upload_progress.set(this.upload_id, sum);
console.log("sum: " + sum);
if (sum == totalChunks) {
this.complete_upload();
}
})
.catch((error) => {
console.error(`${part_num} 上传失败`, error);
});
},
合并分片:
async complete_upload() {
const data = {
bucket_name: this.bucket_name,
object_name: this.file.name,
upload_id: this.upload_id,
};
let res = await func.post(this.upload_addr + '/complete_upload',
data);
}
后端代码:
mux.Handle("/new_multipart_upload",
middleware.Cors(http.HandlerFunc(common.NewMultipartUpload)))
mux.Handle("/presign",
middleware.Cors(http.HandlerFunc(common.Presign)))
mux.Handle("/complete_upload",
middleware.Cors(http.HandlerFunc(common.CompleteMultipartUpload)))
//··························
var (
client *minio.Client
core *minio.Core
)
func InitMinio() {
client = InitMinioClient()
core = &minio.Core{
Client: client,
}
}
func InitMinioClient() *minio.Client {
// 基本的配置信息
endpoint := config.ConfData.Minio.Address + ":" + strconv.Itoa(config.ConfData.Minio.Port)
accessKeyID := config.ConfData.Minio.AccessKeyID
secretAccessKey := config.ConfData.Minio.SecretAccessKey
minioClient, err := minio.New(endpoint, accessKeyID, secretAccessKey, false)
if err != nil {
logx.Fatalf("初始化MinioClient错误:%s", err.Error())
} else {
logx.Info("Minio api start")
}
return minioClient
}
// 获取上传id
func NewMultipartUpload(w http.ResponseWriter, r *http.Request) {
bucketname := r.PostFormValue("bucket_name")
objectname := r.PostFormValue("object_name")
id, err := core.NewMultipartUpload(bucketname, objectname, minio.PutObjectOptions{})
if err != nil {
logx.Errorf("NewMultipartUpload error: %v", err)
httpx.OkJson(w, ResponseData{
Code: CodeInternalServerError,
Msg: "failed to create multipart upload:" + err.Error(),
})
return
}
httpx.OkJson(w, ResponseData{
Code: CodeSuccess,
Msg: "success",
Data: id,
})
}
// 获取上传链接
func Presign(w http.ResponseWriter, r *http.Request) {
bucketname := r.PostFormValue("bucket_name")
objectname := r.PostFormValue("object_name")
uploadID := r.PostFormValue("upload_id")
partNum := r.PostFormValue("part_num")
//这里设置为PUT
url, err := client.Presign("PUT", bucketname, objectname, 100*time.Second, url.Values{
"uploadId": []string{uploadID},
"partNumber": []string{partNum},
})
if err != nil {
logx.Error(err)
}
httpx.OkJson(w, ResponseData{
Code: CodeSuccess,
Msg: "success",
Data: url.String(),
})
}
// 合并分片
func CompleteMultipartUpload(w http.ResponseWriter, r *http.Request) {
bucketname := r.PostFormValue("bucket_name")
objectname := r.PostFormValue("object_name")
upload_id := r.PostFormValue("upload_id")
parts, err := core.ListObjectParts(bucketname, objectname, upload_id, 0, 0)
if err != nil {
logx.Error(err)
}
part_list := make([]minio.CompletePart, 0)
for _, v := range parts.ObjectParts {
item := minio.CompletePart{
PartNumber: v.PartNumber,
ETag: v.ETag,
}
part_list = append(part_list, item)
}
res, err := core.CompleteMultipartUpload(bucketname,
objectname, upload_id,part_list)
if err != nil {
logx.Error(err)
}
logx.Info(res)
httpx.OkJson(w, ResponseData{
Code: CodeSuccess,
Msg: "success",
Data: res,
})
}
GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5
* chore: fix link broken
Signed-off-by: snoppy <michaleli@foxmail.com>
* Update packages/template-compiler/README.md [skip ci]
---------
Signed-off-by: snoppy <michaleli@foxmail.com>
Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891
Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
更多推荐
已为社区贡献2条内容
所有评论(0)