前端使用minio传输文件
minio官方文档
minio-js可以支持ts。
安装完可能会出现
Can‘t import the named export ‘xxx‘ from non EcmaScript module (only default export is available)
可以尝试降低minio的版本
npm install minio@7.0.18 --save
代码:
初始化
const Minio = require('minio')const minioClient = new Minio.Client({endPoint: '192.l68.0.1', //minio服务器ip,不能加http://port: 9000,accessKey: 'xxxx', //usernamesecretKey: 'xxxx', //passworduseSSL: false //https访问需要设置为true
})
上传文件
const stream = require('stream')/**** @export 上传文件(stream流方法)* @param {*} backetName String 存储桶名字* @param {*} fileObj Object 文件对象* @param {*} callback function 回调函数*/
export function uploadFile (backetName, fileObj, callback) {console.log(backetName, fileObj)if (fileObj) {const file = fileObjif (file === undefined) {// 未选择} else {const date = new Date()const year = new Date().getFullYear()const month =date.getMonth() + 1 < 10? '0' + (date.getMonth() + 1): date.getMonth() + 1const day = date.getDate() > 9 ? date.getDate() : '0' + date.getDate()const fileName = date.getTime() + file.nameconst fileDate = '' + year + month + dayconst mineType = file.typeconst fileSize = file.sizeconsole.log('fileName', fileName)// 参数const metadata = {'content-type': mineType,'content-length': fileSize}// 判断储存桶是否存在minioClient.bucketExists(backetName, function (err) {console.log('判断储存桶是否存在')if (err) {if (err.code === 'NoSuchBucket') {return console.log('bucket does not exist.')}console.log('1233221')return console.log(err)}// 准备上传const reader = new FileReader()reader.readAsDataURL(file)reader.onloadend = function (e) {const dataurl = e.target.resultconst blob = toBlob(dataurl)const reader2 = new FileReader()reader2.readAsArrayBuffer(blob)reader2.onload = function (ex) {const bufferStream = new stream.PassThrough()bufferStream.end(Buffer.from(ex.target.result))minioClient.putObject(backetName,`${fileDate}/${fileName}`,bufferStream,fileSize,metadata,(err) => {if (err == null) {minioClient.presignedPutObject(backetName,`${fileDate}/${fileName}`,24 * 60 * 60,function (err1, presignedUrl) {console.log(err1)if (err1) returnif (presignedUrl) {const arr = presignedUrl.split('?')if (arr.length === 2) {callback(arr[0])}}})}})}}})}}
}/**** @export base64转blob* @param {*} base64Data Object base64数据* @return {*} blob*/
export function toBlob (base64Data) {let byteString = base64Dataif (base64Data.split(',')[0].indexOf('base64') >= 0) {byteString = window.atob(base64Data.split(',')[1]) // base64 解码} else {byteString = unescape(base64Data.split(',')[1])}// 获取文件类型const mimeString = base64Data.split(';')[0].split(':')[1] // mime类型const uintArr = new Uint8Array(byteString.length) // 创建视图for (let i = 0; i < byteString.length; i++) {uintArr[i] = byteString.charCodeAt(i)}const blob = new Blob([uintArr], {type: mimeString})return blob
}// 先判断桶是否存在,如果可确保捅已经存在,则直接调用uploadFile方法
export function checkedAndUpload (bucketName, info, callback) {minioClient.bucketExists(bucketName, err => {if (err) {minioClient.makeBucket(bucketName, 'us-east-1', err1 => {if (err1) {console.error(`${info.file.name}文件上传失败`)return}uploadFile(bucketName, info, callback)})} else {uploadFile(bucketName, info, callback)}})
}// 先判断桶是否存在
export function connectionStatus (bucketName, callback) {minioClient.bucketExists(bucketName, err => {console.Log(err)callback(err)})
}
上传文件简单版:
const bucketName = 'picturebook-version'; // 替换为你的存储桶名称
const objectName = file.file.name; // 使用文件名作为对象名称//创建 FileReader 对象
const reader = new FileReader();// 当读取完成时触发的回调函数
reader.onload = (event) => {// 从事件对象中获取文件内容const fileContent = event.target.result;// 转换 ArrayBuffer 为 Buffer 类型数据const buffer = Buffer.from(fileContent);// 使用 putObject 方法上传文件内容this.minioClient.putObject(bucketName, objectName, buffer, buffer.length, (err, etag) => {if (err) {console.error('上传文件失败:', err);} else {this.fileList.push(this.newFile);this.fileName = objectName;console.log('文件上传成功,ETag:', etag);}});
};// 开始读取文件
reader.readAsArrayBuffer(file.file);
下载文件
export function downloadFile (bucketName, fileName, callback) {minioClient.getObject(bucketName, fileName, (err, dataStream) => {callback(err, dataStream)})
}
使用
<div @click="selectFile" style="cursor: pointer; width: 80px; text-align: right"class="ant-upload-text" > 上传 </div>
<input type="file id="uploadInput" ref="uploadInput" v-show="false" @change="changeInput()"/>
import { uploadFile } from '@/utils/minio'selectFile() {const inputDOM = this.$refs.uploadInputinputDOM.click()
},
changeInput() {const file = this.$refs.uploadInput.filesif (file.length) {this.sourceFile = {name: file[0].name,size: file[0].size,type: file[0].type,}uploadFile('carbon', file[0], (e) => {this.$refs.uploadInput.value = ''this.sourceFile = {...this.sourceFile,url: e,}})}
},
拓展
优点:
1.直接访问对象存储:前端直接与 MinIO 通信,而不需要通过后端服务器作为中介。这样可以降低后端服务器的负担,减少网络传输时间,提高文件传输效率。
2.降低后端开发成本:前端直接使用 MinIO SDK 进行文件上传和下载,减少了与后端开发相关的工作量。这样可以加快开发速度,并降低了整体的开发成本。
3.分布式存储支持:MinIO 支持分布式存储,可以在多个节点之间存储数据,实现高可用性和容错性。前端直接与 MinIO 通信,可以利用 MinIO 的分布式特性,将文件分散存储在不同的节点上,提高文件的可靠性和可用性。
4.快速上传和下载:MinIO 针对文件上传和下载进行了优化,提供了快速的传输速度和低延迟的访问体验。前端直接与 MinIO 通信,可以获得更快的上传和下载速度,提高用户体验。
5.可控性和安全性:前端直接使用 MinIO SDK 进行文件上传和下载,可以根据需要设置访问权限、加密方式等安全措施,保护文件的安全性和完整性。同时,前端可以完全掌控文件的访问和管理,保留对文件的完全控制权。
6.跨平台兼容性:MinIO 提供了丰富的客户端 SDK,包括 JavaScript SDK,在各种前端平台(Web、移动端、桌面端)上都可以方便地集成和使用。这样可以实现跨平台的文件上传和下载,满足不同平台的需求。
缺点:
1.只支持Webpack工程化构建的项目,因为webpack是基于nodeJs的,可以使用require, fs等函数
2.不支持Vite工程化构建形式,Vite是EsModule纯浏览器模块的形式,没有nodeJs里的函数,只能使用import,但部分第三方库并不支持,会报奇怪的错误
3.前端直传Minio是无法获取上传进度的,自然也就无法显示进度条,从而无法拥有良好的人机交互感,并且需要等待Minio反馈后才能判断是否上传成功
4.端口,登录账号,登录密码都写在前端,会暴露关键信息,易造成不必要的信息泄露,并且不易维护
5.由前端写Minio接口不利于之后的扩展,每开一个项目,都需要copy代码,无形中增加了维护的困难性
相关文章:
前端使用minio传输文件
minio官方文档 minio-js可以支持ts。 安装完可能会出现 Can‘t import the named export ‘xxx‘ from non EcmaScript module (only default export is available)可以尝试降低minio的版本 npm install minio7.0.18 --save代码: 初始化 const Minio require(…...
[大模型] BlueLM-7B-Chat WebDemo 部署
BlueLM-7B-Chat WebDemo 部署 模型介绍 BlueLM-7B 是由 vivo AI 全球研究院自主研发的大规模预训练语言模型,参数规模为 70 亿。BlueLM-7B 在 C-Eval 和 CMMLU 上均取得领先结果,对比同尺寸开源模型中具有较强的竞争力(截止11月1号)。本次发布共包含 7…...
一文了解ERC404协议
一、ERC404基础讲解 1、什么是ERC404协议 ERC404协议是一种实验性的、混合的ERC20/ERC721实现的,具有原生流动性和碎片化的协议。即该协议可让NFT像代币一样进行拆分交易。是一个图币的互换协议。具有原生流动性和碎片化的协议。 这意味着通过 ERC404 协议…...
iOS cocoapods pod FrozenError and RuntimeError
0x00 报错日志 /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.12.0/lib/cocoapods/user_interface/error_report.rb:34:in force_encoding: cant modify frozen String (FrozenError)from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.12.0/lib/cocoapods/user_interface/error_r…...
【鸿蒙开发】第二十章 Camera相机服务
1 简介 开发者通过调用Camera Kit(相机服务)提供的接口可以开发相机应用,应用通过访问和操作相机硬件,实现基础操作,如预览、拍照和录像;还可以通过接口组合完成更多操作,如控制闪光灯和曝光时间、对焦或调焦等。 2 …...
JS阅读笔记
myweb3.html <video id"video" width"400" height"300" autoplay></video> <button id"capture-btn">拍摄图片</button> <canvas id"canvas" width"400" height"300">&…...
基于spring boot的留守儿童爱心管理系统
基于spring boot的留守儿童爱心管理系统设计与实现 开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7(一定要5.7版本) 数据库工具:Navicat11 开…...
python输入某年某月某日判断这一天是这一年的第几天
如何使用python实现输入某年某月某日判断这一天是这一年的第几天 from datetime import datetime #引入日期类 def is_leap_year(year):"""判断是否为闰年"""return (year % 4 0 and year % 100 ! 0) or (year % 400 0)# 根据年份和月份返回当…...
docker 上达梦导入dump文件报错:本地编码:PG GBK,导入女件编码:PGGB18030
解决方案: 第一步进入达梦数据容器内部 docker exec -it fc316f88caff /bin/bash 第二步:在容器中 /opt/dmdbms/bin目录下 执行命令 cd /opt/dmdbms/bin./dimp USERIDSYSDBA/SYSDBA001 FILE/opt/dmdbms/ZFJG_LJ20240407.dmp SCHEMASZFJG_LJUSERIDSYSD…...
一起学习python——基础篇(19)
今天来说一下python的如何修改文件名称、获取文件大小、读取文中指定的某一行内容。 1、修改文件名称: import os testPath"D:/pythonFile/test.txt" testPath2"D:/pythonFile/test2.txt" #修改文件名称使用rename方法, #第一个参…...
数模 初见数建
文章目录 初见数学建模1.1 数学建模是什么1.2 数学建模的概述1.3 如何学习数学建模---分模块化1.4 数学建模前提了解1.5 数学建模的六个步骤1.6 如何备战建模比赛1.7 数学建模赛题类型1.8 数学建模算法体系概述 初见数学建模 1.1 数学建模是什么 1.原型与模型 原型ÿ…...
windows系统搭建OCR半自动标注工具PaddleOCR
深度学习 文章目录 深度学习前言一、环境搭建准备方式1:安装Anaconda搭建1. Anaconda下载地址: [点击](https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/?CM&OD)2. 创建新的conda环境 方式2. 直接安装python 二、安装CPU版本1. 安装PaddlePaddle2、安装…...
01、ArcGIS For JavaScript 4.29对3DTiles数据的支持
综述 Cesium从1.99版本开始支持I3S服务的加载,到目前位置,已经支持I3S的倾斜模型、3D Object模型以及属性查询的支持。Cesium1.115又对I3S标准的Building数据实现了加载支持。而ArcGIS之前一直没有跨越对3DTiles数据的支持,所以在一些开发过…...
Spark_SparkSql写入Oracle_Undefined function.....将长字符串写入Oracle中方法..
在使用Spark编写代码将读库处理然后写入Oracle中遇到了诸多小bug,很磨人,好在解决了。shit!! 实测1:TO_CLOB(a3) 代码样例 --这是一个sparksql写入hive的一个小逻辑,我脱敏了噻 SELECT a1, a2, TO_CLOB(a3) AS clob_data, TO_DATE(a4) AS …...
2023数据要素白皮书(免费下载)
【1】关注本公众号,转发当前文章到微信朋友圈 【2】私信发送 【2023年数据资源入表白皮书】 【3】获取本方案PDF下载链接,直接下载即可。 如需下载本方案PPT原格式,请加入微信扫描以下方案驿站知识星球,获取上万份PPT解决方案&a…...
kafka学习记录
文章目录 windows单机版kafka搭建步骤主题的增删改查操作消息的生产与消费 Windows集群版kafka搭建步骤 prettyZoo 尚硅谷Kafka教程,2024新版kafka视频,零基础入门到实战 【尚硅谷】Kafka3.x教程(从入门到调优,深入全面࿰…...
无线网络2.4和5G的区别
无线网络2.4和5的区别 无线网络2.4GHz和5GHz的主要区别在于频率、覆盖范围、传输速度、干扰能力和穿透性。以下是详细介绍:12 频率不同。2.4GHz的频率较低,而5GHz的频率较高。频率越低,信号在传播过程中的损失越小,因此覆盖范围…...
大模型笔记:Prompt tuning
1 NLP模型的几个阶段 1.1 第一阶段(在深度学习出现之前) 通常聚焦于特征工程(feature engineering)利用领域知识从数据中提取好的特征 1.2 第二阶段(在深度学习出现之后) 特征可以从数据中习得——>…...
【Ambari】Ansible自动化部署大数据集群
目录 一.版本说明和介绍信息 1.1 大数据组件版本 1.2 Apache Components 1.3 Databases支持版本 二.安装包上传和说明 三.服务器基础环境配置 3.1global配置修改 3.2主机名映射配置 3.3免密用户名密码配置 3.4 ansible安装 四. 安…...
RTSP/Onvif视频安防监控平台EasyNVR调用接口返回匿名用户名和密码的原因排查
视频安防监控平台EasyNVR可支持设备通过RTSP/Onvif协议接入,并能对接入的视频流进行处理与多端分发,包括RTSP、RTMP、HTTP-FLV、WS-FLV、HLS、WebRTC等多种格式。平台拓展性强、支持二次开发与集成,可应用在景区、校园、水利、社区、工地等场…...
告别‘阴阳屏’:深入MTK平台PQ底层,教你用代码实现多供应商屏幕色彩统一
MTK平台屏幕色彩统一实战:从Gamma参数调试到自动化加载 当你的项目同时采用三家不同供应商的屏幕模组时,用户滑动屏幕时可能看到三种截然不同的白色——这种"阴阳屏"现象在硬件采购多元化的今天越来越普遍。作为深耕显示领域多年的工程师&…...
计算机毕业设计springboot众筹系统 基于SpringBoot的校园项目众筹融资平台设计与实现 高校创新创业众筹服务与资金管理系统构建研究
计算机毕业设计springboot众筹系统(配套有源码 程序 mysql数据库 论文) 本套源码可以在文本联xi,先看具体系统功能演示视频领取,可分享源码参考。 随着我国经济的高速发展与人们生活水平的日益提高,人们对生活质量的追求也多种多样…...
手把手教你用魔塔社区+LLaMA-Factory,免费微调Qwen2.5-7B模型(保姆级避坑指南)
零成本玩转Qwen2.5-7B微调:魔塔社区LLaMA-Factory实战手册 最近在开源模型社区里,Qwen2.5系列凭借其优秀的对话能力和中文理解表现,迅速成为开发者们的新宠。但很多朋友反馈,虽然想尝试微调这个模型来适配自己的业务场景ÿ…...
寻音捉影·侠客行多场景落地:覆盖会议/媒体/司法/金融/教育五大垂直领域
寻音捉影侠客行多场景落地:覆盖会议/媒体/司法/金融/教育五大垂直领域 1. 产品核心功能解析 寻音捉影侠客行是一款基于先进语音识别技术的音频关键词检索工具,它能够像江湖中的隐士高手一样,在浩瀚的音频海洋中精准定位特定关键词。这款工具…...
Leetcode 数据结构刷题 ->链表1
[27. 移除元素]移除等于所给值的元素,我们可以直接使用双指针,对着来的。关键就是把不等于x的值(我改一下,没用val),放到后面去,这样前面就全部都是不等于x值,再计数即可。看代码就对…...
wan2.1-vae开源可部署:支持国产操作系统(麒麟/UOS)的适配方案
wan2.1-vae开源可部署:支持国产操作系统(麒麟/UOS)的适配方案 1. 平台介绍 muse/wan2.1-vae 文生图是基于 Qwen-Image-2512 模型的AI图像生成平台,支持中英文提示词,可生成高质量、高分辨率的图像。该平台特别针对国…...
最完整的大模型算法工程师技术栈图谱(2026版)
目录 一、基础能力(所有AI工程师的底座) 1 编程语言 2 数据结构与算法 3 数学基础 二、深度学习基础 深度学习模型基础 三、大模型核心技术 1 Transformer架构 2 预训练 3 Tokenizer 四、大模型训练体系 1 分布式训练 2 训练优化技术 3 微…...
从FCN到U-Net:盘点深度学习图像分割中,那些‘放大’特征图的秘密武器与选型指南
从FCN到U-Net:解码图像分割中的特征图放大技术选型 在构建图像分割模型时,特征图的上采样操作往往是决定最终分割精度的关键环节之一。不同于分类任务只需输出一个类别标签,分割网络需要对每个像素进行分类,这就要求网络能够将低分…...
一条命令搞定STM32程序下载:OpenOCD program命令的隐藏用法与避坑指南
STM32极速烧录秘籍:OpenOCD program命令高阶玩法全解析 每次调试STM32都要重复点击IDE的下载按钮?CI/CD流水线卡在烧录环节?是时候解锁OpenOCD的program命令了——这个被低估的"瑞士军刀"能让你用一行命令完成擦除、烧录、校验、复…...
离散数学实战:用Python解决图论问题(附完整代码示例)
离散数学实战:用Python解决图论问题(附完整代码示例) 当你在社交软件上查看"可能认识的人"推荐,或是用导航软件规划最短路线时,背后都在运行图论算法。作为离散数学中最具工程价值的领域,图论将现…...
