使用js上传文件到minio,从minio下载文件

前端上传文件到minio,并从minio下载下来此文件。
api: https://docs.min.io/docs/javascript-client-api-reference.html

我在react中使用的,在index.js中引入下方minio.js

/*
 services: minio配置信息
  {
    endPoint: 'hostname',
    port: 9000,
    useSSL: true,         //  true:https   false:http
    accessKey: 'Q3AM3UQ867SPQQA43P2F',
    secretKey: 'zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG'
  }
*/

// 上传文件
onChange =(info) => {
  const { clientVersion: { services } } = this.props;
  const { fileList } = this.state;
  // 删除文件
  if (info.file.status === 'removed') {
    this.setState({
      filePath:'',
    });
  }
  // 显示上传文件列表
  this.setState({
    fileList: info.fileList,
  });
  // minio config
  minioConfig(services);
//client-version-file这个桶是是事先在minio上创建好的
  connectionStatus('client-version-file', err => {
  // 连接失败会返回err
    if (err !== null && fileList.length === 0) {
      this.setState({
        fileList: [],
      });
      message.warning('存储服务器连接失败');
      return false;
    }
    // 限制只能上传三个文件
    if(info.fileList.Length > 1) {
      message.warn('一个版本只能上传一个文件');
      return false;
    }
    // 限制上传文件的类型
    if (info.file.name.index0f('.apk') === -1){
      message.warn('必须上传以.apk为后缀的文件');
      return false;
    }
    // 上传成功提示
    if (info.file.status === 'done' && fileList.Length ===1){
      checkedAndUpLoad('client-version-file', info, res => {
        // 输出url
        message.success(`${info.file.name}文件上传成功`);
        this.setstate({
          filePath:res,
        });
      });
    } else if (info.file.status === 'error') {
        message.error(`${info.file.name}文件上传失败`);
    }
  });
};

// render

// render() {
//   // 上传文件 调用minio进行上传
//   const uploadProps = {
//     name: 'file',
//     accept: 'apk',
//     headers: {
//       authorization: 'authorization-text',
//     },
//     fileList,
//     onChange: this.onChange,
//   };
//   return (
//     <Upload.Dragger>
//       <p className="antd-upload-drag-icon">
//        <Icon type="inbox" />
//       </p>
//       <p className="antd-upload-text">见文件拖拽到此处,或者点击上传</p>
//     </Upload.Dragger>
//   )
// }

// 下载文件
downloadFile =(url) => {
  const { clientVersion: { services } } = this.props;
  const fileName = url.substring(url.lastIndex0f('/') + 1);
  Let size =0;
  const list = new Array();
  minioConfig(services);
  // download( bucketName fileName callback)
  download('client-version-file', fileName, (err,datastream)=>{
    if (err){
      return message.warn(content: '存储服务器连接失败');
    }
    message.success( content: '已开始下载,请稍后');
    dataStream.on('data' , (chunk)=>{
      size +=chunk.Length;
      List.push(chunk);
    });
    dataStream.on('end', () =>
    const u8arr =new Uint8Array(size);
    Let u8arrindex= 0;
    for (Let i=0; i<list.Length; i++) {
      for (Let j = 0; j < list[i].length; j++) {
        u8arr[u8arrindex] = list[i][j];
        u8arrindex+=1;
      }
    }
    Let fileType = '';
    switch (fileName.substring(fileName.lastIndex0f('.') +1)) {
      case 'apk':
        fileType = 'application/vnd.android.package-archive' ;
    }
    const file = new File( fileBits: [u8arr], fileName: '', options: { type: fileType });
    const blob = new Blob( blobParts: [file]);
    const Link = document.createElement( tagName: 'a');
    Link.href =window.URL.createobjectURL(bLob);
    Link.download = url.substring(url.lastIndex0f('/') +1);
    Link.click();
    window.URL.revokeObjectURL(Link.href);
    });
    dataStream.on('error', (err) => {
      console.Log(err);
    });
  });
};

/*
* minio.js
* */

// 上传文件需要的配置
const Minio = require('minio');
const stream = require('stream');
// 你的minio配置信息
Let minioClient = {};
// 在页面调用,先连接服务区
export function minioConfig(confiq){
  minioClient=new Minio.Client(confiq);
}

// base64转blob
export function toBlob(base64Data) {
  Let byteString = base64Data;
  if (base64Data.split(',')[@].index0f('base64') >= 0) {
    byteString = atob(base64Data.split(',')[1]); // base64 解码
  }else{
    byteString = unescape(base64Data.split(',')[1]);
  }
  // 获取文件类型
  const mimeString = base64Data.split(';')[@].split(':')[1]; // mime类型

  // ArrayBuffer 对象用来表示通用的、固定长度的原始二进制数据缓冲区
  // let arrayBuffer =new ArrayBuffer(byteString.length) // 创建缓冲数组
  // Let uintArr =new Uint8Array(arrayBuffer) // 创建视图

  const uintArr = new Uint8Array(byteString.Length); // 创建视图

  for (Let i = 0; i < byteString.Length; i += 1){
    uintArr[i] =byteString.charCodeAt(i);
  }
  // 生成blob
  const blob =new Blob( blobParts:[uintArr], options:{
    type:mimeString,
  });
  // 使用 Blob 创建一个指向类型化数组的URL,URL.createObjectURL是new BLob
  // 文件的方法,可以生成一个普通的url,可以直接使用,比如用在img.src上
  return blob;
}

/*上传文件
*@param {*} bucketName 桶名
*@param {*} info info为antd上传组件的info
*@param {*} callback 回调函数,返回下载url
*/
export function uploadFile(bucketName,info,callback) {
  // 获取文件类型及大小
  const fileName = info.file.name;
  const mineType = info.file.type;
  const filesize = info.file.size;
  // 参数
  const metadata = {
    'content-type': mineType,
    'content-Length': fileSize,
  };
  // 将文件转换为minio可接收的格式
  const reader = new FileReader();
  reader.readAsDataURL(info.file.originFile0bj);
  reader.onLoadend = e => {
    const dataurl = e.target.result;
    // base64转blob
    const blob = toBlob(dataurl);
    // blob转arrayBuffer
    const reader2 = new FileReader();
    reader2.readAsArrayBuffer(blob);
    reader2.onload = ex => {
      // 定义流
      const bufferStream = new stream.PassThrough();
      // 将buffer写入
      bufferStream.end(Buffer.from(ex.target.result));
      // 上传
      minioClient.putobject(bucketName, fileName, bufferStream, fileSize, metadata, err => {
        console.Log(err);
        if (err == null) {
          // 获取url
          minioClient.presignedGetobject(bucketName, fileName, 24 * 60 * 60, (err1, presignedUrl) => {
            console.Log(err1);
            if (err1) return;
            // 将数据返回
            callback(presiqnedUrl);
          });
        }
      });
    };
  };
}

// 先判断桶是否存在,如果可确保捅已经存在,则直接调用upload方法
export function checkedAndUpload(bucketName, info, callback){
  minioClient.bucketExists(bucketName, err => {
    if(err){
      minioclient.makeBucket(bucketName, 'us-east-1', err1 => {
        if(err1) {
          consle.error(`${info.file.name}文件上传失败`);
          return;
        }
        uploadFile(bucketName,info, callback);
      });
    }else {
      uploadFile(bucketName, info, callback);
    }
  });
}

// 先判断桶是否存在,如果确保桶已经存在,则直接调用upload方法
export function connectionStatus(bucketName, callback) {
  minioClient.bucketExists(bucketName, err => {
    console.Log(err);
    callback(err);
  });
}

export function download(bucketName, fileName, callback) {
  minioClient.getobject(bucketName, fileName, (err, dataStream) => {
    callback(err, dataStream);
  });
}


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容