前端直接上传文件到minio

news2024/9/30 19:22:51

前端上传文件到minio

文章目录

  • 前端上传文件到minio
    • 1. 实现步骤
    • 2. 修改
        • a. 图片破损问题
        • b.拿不到文件链接
        • c.文件名称
    • 3.总结代码

项目有需要前端来直接上传文件到minio,由于这里我没看懂官网的文档,所以直接在网上搜的教程,这里主要是讲述一下我遇到的一些问题

1. 实现步骤

下面的代码是我搜到的比较简短的实现步骤

<template>
  <div>
    <input type="file" @change="onFileChange" />
    <button @click="uploadFile" :disabled="!file">上传</button>
    <div v-if="progress > 0">上传进度: {{ progress }}%</div>
    <div v-if="error" style="color: red;">错误: {{ error }}</div>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
      file: null,
      progress: 0,
      error: null,
    };
  },
  methods: {
    onFileChange(event) {
      this.file = event.target.files[0];
    },
    async uploadFile() {
      if (!this.file) return;

      const url = 'http://<minio-server-url>/<bucket-name>/<object-name>'; // 替换为实际的 MinIO 地址和目标存储桶

      const formData = new FormData();
      formData.append('file', this.file);

      try {
        const response = await axios.put(url, formData, {
          headers: {
            'Content-Type': this.file.type,
            'Authorization': `Bearer <your-access-token>` // 如果需要身份验证,请提供访问令牌
          },
          onUploadProgress: (progressEvent) => {
            this.progress = Math.round((progressEvent.loaded * 100) / progressEvent.total);
          }
        });
        console.log('上传成功:', response.data);
        this.progress = 0; // 重置进度
      } catch (err) {
        this.error = err.message;
        console.error('上传失败:', err);
      }
    },
  },
};
</script>

<style scoped>
/* 添加你的样式 */
</style>

minio-server-url、bucket-name、object-name、your-access-token这里根据自己minio上的设置自行替换

2. 修改

a. 图片破损问题

首先我通过上述的步骤实现了上传,但上传后的图片并不能正常显示,下载后打开显示图片破损
原因: 我们使用的是axios.put上传文件,put请求不需要使用formData,formData适合post请求上传数据,如果用put请求上传文件,文件的原始二进制内容应该直接作为请求体发送,而不是使用formData

这里我们将以下代码进行替换
const formData = new FormData();
formData.append(‘file’, this.file);
替换成
const formData=await this.file.arrayBuffer()

替换后,上传成功并在minio控制台可以预览出来图片,之前一直是加载图片,预览不了

b.拿不到文件链接

上传文件成功后,minio并没有返回他的链接,res.data=‘’, 因此这里我们需要自行构建

const response = await axios.put(url, formData, {
          headers: {
            'Content-Type': this.file.type,
            'Authorization': `Bearer <your-access-token>` // 如果需要身份验证,请提供访问令牌
          },
          onUploadProgress: (progressEvent) => {
            this.progress = Math.round((progressEvent.loaded * 100) / progressEvent.total);
          }
        });
        const fileUrl='http://<minio-server-url>/<bucket-name>/<object-name>'
        console.log('上传成功:', response.data);
c.文件名称

有时上传文件的名称可能会有重名,因此这里可以用时间戳进行一个拼接

 const fileName= file.name?`${Date.now()}_${file.name}`:`${Date.now()}_${file.raw.name}`

3.总结代码

以上是用type为file的input作为案例进行演示,如果用组件库,例如element-plus中的el-upload的话,文件内容会嵌套一层

<template>
  <el-upload :auto-upload="false" v-bind="$attrs" :disabled="disabled" v-model:file-list="fileList"
             :on-preview="handlePictureCardPreview" ref="upload">
    //这里的一些不涉及本文章的方法就不再下面的代码中进行赘述了,有需要请参考上篇文章
    <template #file="{file}">
      <div class="file-list-item cursor-pointer">
        <!-- 点击预览 -->
        <span @click="handlePictureCardPreview(file)" class="flex-1">{{ file.name }}</span>

        <!-- 显示进度条 -->
        <el-progress class="mt-2" :stroke-width="3" color="#409eff" v-if="file.status === 'ready' && file.percentage !== 0" :percentage="file.percentage" />

        <!-- 显示文件上传状态 -->
        <span v-if="file.status === 'success'" style="color: green;"><el-icon><CircleCheck /></el-icon></span>
        <span v-if="file.status === 'fail'" style="color: red;"><el-icon><CircleClose /></el-icon></span>

        <!-- 删除文件 -->
        <el-button class="w-[50px] h-[32px] border-[0] text-[20px] delete-btn" icon="close" @click="handleRemove(file)" />

      </div>
    </template>
  </el-upload>
  <el-dialog v-model="dialogVisible">
    <img class="w-full" :src="dialogImageUrl" alt="Preview Image" />
  </el-dialog>
</template>
 async sureUpload() {
      for (const file of this.fileList) {
        if (file.status !== 'ready') {
          continue
        }
        let res = await this.uploadEleFile(file)
        if (res) {
          file.url = res.link
          file.name=res.name
        }
      }
      this.$emit('update:modelValue', this.fileList.map(a => { return { url: a.url, name: a.name } }))
},
async uploadEleFile(file){
            if(!file) return
            const fileName= file.name?`${Date.now()}_${file.name}`:`${Date.now()}_${file.raw.name}`
            const url=`${server}:${post}/${bucket}/${fileName}`
            const fileData = await file.raw.arrayBuffer();

            return new Promise(async (resolve,reject)=>{
                let res;
                try {
                    res = await axios.put(url, fileData, {
                        headers: {
                            'Content-Type': file.raw.type,
                            'Authorization': `Bearer ${accessKey}`
                        },
                        // 监听上传进度
                        onUploadProgress: (progressEvent) => {
                            if (progressEvent.progress) {
                                const percentCompleted = Math.round(
                                    (progressEvent.loaded * 100) / progressEvent.total
                                );
                                // 更新进度
                                file.percentage = percentCompleted;
                            }
                        },
                    });
                    if(res.status===200){
                        file.status = 'success'
                        const url=`${server}:${post}/${bucket}/${fileName}`
                        resolve({link:url,name:file.name})
                    }
                    console.log('上传成功:', res);
                } catch (error) {
                    file.status = 'fail'
                    this.$message.error('上传失败,请重新选择素材进行上传')
                    reject(error)
                }
            })
        },

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2180492.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

prometheus + alertmanager + PrometheusAlert实现告警

prometheus 收集监控数据 alertmanager 制定告警路由 PrometheusAlert 连通告警webhook 一、prometheus配置 https://prometheus.io/download/ 1.1、prometheus安装 包的下载直接wget就行,放在data目录下,解压后在prometheus目录下创建config和rule目录 配置了热重启&#…

聊一聊 C#中有趣的 SourceGenerator生成器

一&#xff1a;背景 1. 讲故事 前些天在看 AOT的时候关注了下 源生成器&#xff0c;挺有意思的一个东西&#xff0c;今天写一篇文章简单的分享下。 二&#xff1a;源生成器探究之旅 1. 源生成器是什么 简单来说&#xff0c;源生成器是Roslyn编译器给程序员开的一道口子&am…

vxe-grid给单元格加上触发事件

效果&#xff1a;输入框的双击事件(其他事件可以由此替换) 代码 // gridTableOptions是每列的配置项 <vxe-grid v-bind"gridTableOptions" :data"goodsList" ref"xTable">// edit_spbh 是对应的样式名&#xff0c;是写在gridTableOption…

如何通过日志快速定位TTS的缓存放音文件(mod_cti基于FreeSWITCH)

文章目录 前言联系我们分析过程1. 测试话术&#xff0c;记录日志2. 关键词搜索 前言 顶顶通呼叫中心中间件在运行话术时&#xff0c;如果有通过TTS合成的语音&#xff0c;会被freeswitch缓存在目录中&#xff1a;/ddt/fs/storage/http_file_cache。 我们可以分析freeswitch日志…

学习Webpack中图片-JS-Vue-plugin

目录 图片文件资源模块类型 JS文件babel命令行使用babel-loaderbabel-preset Vue文件vue-loadervue/compiler-sfc pluginCleanWebpackPluginHtmlWebpackPluginDefinePlugin 图片文件 需要先在项目中使用图片&#xff0c;比较常见的使用图片的方式是两种&#xff1a; img元素&…

LeetCode 918. 环形子数组的最大和

原题链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 给定一个长度为 n 的环形整数数组 nums &#xff0c;返回 nums 的非空 子数组 的最大可能和 。 环形数组 意味着数组的末端将会与开头相连呈环状。形式上&#xff0c; nums[i] 的下一个元素是 nums[(i 1) % n…

基于STM32的智能室内空气质量监控系统

目录 引言项目背景环境准备 硬件准备软件安装与配置系统设计 系统架构关键技术代码示例 传感器数据采集与处理空气质量分析与报警显示与数据记录功能应用场景结论 1. 引言 智能室内空气质量监控系统用于实时监测环境中的空气质量&#xff0c;通过检测空气中的CO2、PM2.5、温…

软件测试学习笔记丨Pytest 学习指南

本文转自测试人社区&#xff0c;原文链接&#xff1a;https://ceshiren.com/t/topic/32336 基本介绍 pytest框架是一个成熟&#xff0c;全面的测试框架&#xff0c;具有非常丰富的第三方插件&#xff0c;并且可以自定义扩展 比如&#xff1a;pytest-selenium , pytest-html ,…

Git常用方法——详解

一、下载安装git git官网&#xff1a; Git - Downloads (git-scm.com) 下载安装Git&#xff08;超详细超简单&#xff09;_git下载-CSDN博客 二、克隆下载至本地 1、复制HTTPS链接 在gitee或者gitLab或者gitHub上复制HTTPS链接 2、打开Open Git Bash here 在本地想要新建文…

小程序原生-列表渲染

1. 列表渲染的基础用法 <!--渲染数组列表--> <view wx:for"{{numList}}" wx:key"*this" > 序号&#xff1a;{{index}} - 元素&#xff1a;{{item}}</view> <!--渲染对象属性--> <view wx:for"{{userInfo}}" wx:key&q…

怎么给视频加片头片尾和字幕

在这个视觉内容爆炸的时代&#xff0c;一段精心制作的视频不仅能吸引眼球&#xff0c;更能传达深刻的情感与信息。而一个引人入胜的片头、一个温馨感人的片尾&#xff0c;以及恰到好处的字幕&#xff0c;无疑是提升视频质感的关键。那么新人要怎么给视频加片头片尾和字幕效果呢…

2024年9月收评

金1是从2005年12月开始&#xff0c;到现在2024年5月&#xff0c;还差7个月整整20年。一共11轮。 这20年里&#xff0c;真正形成单边趋势&#xff0c;能较好获利或者说至少不亏损的一共有以下几次&#xff0c; 第1轮&#xff0c;第2轮&#xff0c;第7轮&#xff0c;第8轮&…

《程序猿之Redis缓存实战 · 集合类型》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

基于微信小程序的商品展示+ssm论文ppt源码调试讲解

2 系统开发环境 2.1微信开发者工具 微信开发者工具现在已经被小程序开发团队开发运行&#xff0c;目前微信开发者工具任然在不断的完善中&#xff0c;在开发小程序时经常要不断的更新。可以使用微信扫码登陆开发者工具&#xff0c;开发者工具将使用这个微信帐号的信息进行小程…

为VRoidStudio制作的vrm格式模型制作blendshape

零、效果展示 bs视频演示 一、准备相关插件 1、VRoidStudio&#xff08;免费&#xff09; 下载网址&#xff1a;https://vroid.com/en/studio 2、UniVRM&#xff08;免费&#xff09; 下载网址&#xff1a;https://github.com/vrm-c/UniVRM/releases 注意&#xff1a;unity…

Qt --- 常用控件的介绍---Widget属性介绍

一、控件概述 编程&#xff0c;讲究的是站在巨人的肩膀上&#xff0c;而不是从头发明轮子。一个图形化界面上的内容&#xff0c;不需要咱们全都从零区实现&#xff0c;Qt中已经提供了很多内置的控件了&#xff08;按钮&#xff0c;文本框&#xff0c;单选按钮&#xff0c;复选…

yolov8实例分割重要图片

训练分割要准备好数据集和分割预训练权重文件 下面这张图是数据集的格式 下面这张图配置数据集&#xff0c;下面names 要和labelme转txt里配置的一样 下面这张图进行训练&#xff0c;配置一些全局参数 &#xff0c;初始的yolov8s-seg.pt文件需要到github上yolov8开源项目里下 l…

linux部署redis,整合ansible和redis

准备服务器192.168.45.133&#xff0c;192.168.45.135 在135上执行命令yum install -y redis安装redis yum install -y redis 源码安装方法 wget http://download.redis.io/releases/redis-2.8.13.tar.gz tar zxf redis-2.8.13.tar.gz cd redis-2.8.13 make PREFIX/usr/loca…

Cannon-es.js之Distance Constrait模拟布料

本文目录 前言1、Particle2、前置代码准备2.1 代码2.2 效果 3、使用距离约束模拟布料3.1 代码3.2 效果 前言 在现代Web开发中&#xff0c;实现逼真的物理效果对于提升用户体验至关重要。Cannon-es.js&#xff0c;作为Cannon.js的ES6模块版本&#xff0c;凭借其轻量级、高性能和…

selenium测试框架快速搭建详解

一、介绍 Selenium目前主流的web自动化测试框架&#xff1b;支持多种编程语言Java、pythan、go、js等&#xff1b;selenium 提供一系列的api 供我们使用&#xff0c;因此在web测试时我们要点页面中的某一个按钮&#xff0c;那么我们只需要获取页面&#xff0c;然后根据id或者n…